提交 0880691a 编写于 作者: S Sandeep Somavarapu

Implement #41751

上级 49f938b9
......@@ -7,7 +7,12 @@
import { NodeCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { LanguagePackExtensions } from 'vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions';
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
export function createSharedProcessContributions(service: IInstantiationService): void {
service.createInstance(NodeCachedDataCleaner);
export function createSharedProcessContributions(service: IInstantiationService): IDisposable {
return combinedDisposable([
service.createInstance(NodeCachedDataCleaner),
service.createInstance(LanguagePackExtensions)
]);
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as pfs from 'vs/base/node/pfs';
import { IExtensionManagementService, ILocalExtension, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
import { Disposable } from 'vs/base/common/lifecycle';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { join } from 'vs/base/common/paths';
import { TPromise } from 'vs/base/common/winjs.base';
import { Limiter } from 'vs/base/common/async';
import { areSameExtensions, getGalleryExtensionIdFromLocal, getIdFromLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ILogService } from 'vs/platform/log/common/log';
interface ILanguageSource {
extensionIdentifier: IExtensionIdentifier;
path: string;
}
export class LanguagePackExtensions extends Disposable {
private languagePacksFilePath: string;
private languagePacksFileLimiter: Limiter<void>;
constructor(
@IExtensionManagementService private extensionManagementService: IExtensionManagementService,
@IEnvironmentService environmentService: IEnvironmentService,
@ILogService private logService: ILogService
) {
super();
this.languagePacksFilePath = join(environmentService.userDataPath, 'languagepacks.json');
this.languagePacksFileLimiter = new Limiter(1);
this._register(extensionManagementService.onDidInstallExtension(({ local }) => this.onDidInstallExtension(local)));
this._register(extensionManagementService.onDidUninstallExtension(({ identifier }) => this.onDidUninstallExtension(identifier)));
this.reset();
}
private reset(): void {
this.extensionManagementService.getInstalled()
.then(installed => {
this.withLanguagePacks(languagePacks => {
for (const language of Object.keys(languagePacks)) {
languagePacks[language] = [];
}
this.addLanguagePacksFromExtensions(languagePacks, ...installed);
});
});
}
private onDidInstallExtension(extension: ILocalExtension): void {
if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length) {
this.logService.debug('Adding language packs from the extension', extension.identifier.id);
this.withLanguagePacks(languagePacks => {
this.removeLanguagePacksFromExtensions(languagePacks, { id: getGalleryExtensionIdFromLocal(extension), uuid: extension.identifier.uuid });
this.addLanguagePacksFromExtensions(languagePacks, extension);
});
}
}
private onDidUninstallExtension(identifier: IExtensionIdentifier): void {
this.logService.debug('Removing language packs from the extension', identifier.id);
this.withLanguagePacks(languagePacks => this.removeLanguagePacksFromExtensions(languagePacks, { id: getIdFromLocalExtensionId(identifier.id), uuid: identifier.uuid }));
}
private addLanguagePacksFromExtensions(languagePacks: { [language: string]: ILanguageSource[] }, ...extensions: ILocalExtension[]): void {
for (const extension of extensions) {
if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length) {
const extensionIdentifier = { id: getGalleryExtensionIdFromLocal(extension), uuid: extension.identifier.uuid };
for (const localeContribution of extension.manifest.contributes.locales) {
const languageSources = languagePacks[localeContribution.locale] || [];
languageSources.splice(0, 0, { extensionIdentifier, path: join(extension.path, localeContribution.path) });
languagePacks[localeContribution.locale] = languageSources;
}
}
}
}
private removeLanguagePacksFromExtensions(languagePacks: { [language: string]: ILanguageSource[] }, ...extensionIdentifiers: IExtensionIdentifier[]): void {
for (const language of Object.keys(languagePacks)) {
languagePacks[language] = languagePacks[language].filter(languageSource => !extensionIdentifiers.some(extensionIdentifier => areSameExtensions(extensionIdentifier, languageSource.extensionIdentifier)));
}
}
private withLanguagePacks<T>(fn: (languagePacks: { [language: string]: ILanguageSource[] }) => T): TPromise<T> {
return this.languagePacksFileLimiter.queue(() => {
let result: T = null;
return pfs.readFile(this.languagePacksFilePath, 'utf8')
.then(null, err => err.code === 'ENOENT' ? TPromise.as('{}') : TPromise.wrapError(err))
.then<{ [language: string]: ILanguageSource[] }>(raw => { try { return JSON.parse(raw); } catch (e) { return {}; } })
.then(languagePacks => { result = fn(languagePacks); return languagePacks; })
.then(languagePacks => {
for (const language of Object.keys(languagePacks)) {
if (!(languagePacks[language] && languagePacks[language].length)) {
delete languagePacks[language];
}
}
const raw = JSON.stringify(languagePacks);
this.logService.debug('Writing language packs', raw);
return pfs.writeFile(this.languagePacksFilePath, raw);
})
.then(() => result, error => this.logService.error(error));
});
}
}
\ No newline at end of file
......@@ -85,6 +85,11 @@ export interface IColor {
defaults: { light: string, dark: string, highContrast: string };
}
export interface ILocale {
locale: string;
path: string;
}
export interface IExtensionContributions {
commands?: ICommand[];
configuration?: IConfiguration;
......@@ -98,7 +103,8 @@ export interface IExtensionContributions {
themes?: ITheme[];
iconThemes?: ITheme[];
views?: { [location: string]: IView[] };
colors: IColor[];
colors?: IColor[];
locales?: ILocale[];
}
export interface IExtensionManifest {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册