mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
53
src/vs/platform/localizations/common/localizations.ts
Normal file
53
src/vs/platform/localizations/common/localizations.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import Event from 'vs/base/common/event';
|
||||
|
||||
export interface ILocalization {
|
||||
languageId: string;
|
||||
languageName?: string;
|
||||
languageNameLocalized?: string;
|
||||
translations: ITranslation[];
|
||||
}
|
||||
|
||||
export interface ITranslation {
|
||||
id: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export const ILocalizationsService = createDecorator<ILocalizationsService>('localizationsService');
|
||||
export interface ILocalizationsService {
|
||||
_serviceBrand: any;
|
||||
|
||||
readonly onDidLanguagesChange: Event<void>;
|
||||
getLanguageIds(): TPromise<string[]>;
|
||||
}
|
||||
|
||||
export function isValidLocalization(localization: ILocalization): boolean {
|
||||
if (typeof localization.languageId !== 'string') {
|
||||
return false;
|
||||
}
|
||||
if (!Array.isArray(localization.translations) || localization.translations.length === 0) {
|
||||
return false;
|
||||
}
|
||||
for (const translation of localization.translations) {
|
||||
if (typeof translation.id !== 'string') {
|
||||
return false;
|
||||
}
|
||||
if (typeof translation.path !== 'string') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (localization.languageName && typeof localization.languageName !== 'string') {
|
||||
return false;
|
||||
}
|
||||
if (localization.languageNameLocalized && typeof localization.languageNameLocalized !== 'string') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
48
src/vs/platform/localizations/common/localizationsIpc.ts
Normal file
48
src/vs/platform/localizations/common/localizationsIpc.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc';
|
||||
import Event, { buffer } from 'vs/base/common/event';
|
||||
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||
|
||||
export interface ILocalizationsChannel extends IChannel {
|
||||
call(command: 'event:onDidLanguagesChange'): TPromise<void>;
|
||||
call(command: 'getLanguageIds'): TPromise<string[]>;
|
||||
call(command: string, arg?: any): TPromise<any>;
|
||||
}
|
||||
|
||||
export class LocalizationsChannel implements ILocalizationsChannel {
|
||||
|
||||
onDidLanguagesChange: Event<void>;
|
||||
|
||||
constructor(private service: ILocalizationsService) {
|
||||
this.onDidLanguagesChange = buffer(service.onDidLanguagesChange, true);
|
||||
}
|
||||
|
||||
call(command: string, arg?: any): TPromise<any> {
|
||||
switch (command) {
|
||||
case 'event:onDidLanguagesChange': return eventToCall(this.onDidLanguagesChange);
|
||||
case 'getLanguageIds': return this.service.getLanguageIds();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export class LocalizationsChannelClient implements ILocalizationsService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(private channel: ILocalizationsChannel) { }
|
||||
|
||||
private _onDidLanguagesChange = eventFromCall<void>(this.channel, 'event:onDidLanguagesChange');
|
||||
get onDidLanguagesChange(): Event<void> { return this._onDidLanguagesChange; }
|
||||
|
||||
getLanguageIds(): TPromise<string[]> {
|
||||
return this.channel.call('getLanguageIds');
|
||||
}
|
||||
}
|
||||
188
src/vs/platform/localizations/node/localizations.ts
Normal file
188
src/vs/platform/localizations/node/localizations.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { createHash } from 'crypto';
|
||||
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';
|
||||
import { isValidLocalization, ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||
import product from 'vs/platform/node/product';
|
||||
import { distinct, equals } from 'vs/base/common/arrays';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
|
||||
interface ILanguagePack {
|
||||
hash: string;
|
||||
extensions: {
|
||||
extensionIdentifier: IExtensionIdentifier;
|
||||
version: string;
|
||||
}[];
|
||||
translations: { [id: string]: string };
|
||||
}
|
||||
|
||||
const systemLanguages: string[] = ['de', 'en', 'en-US', 'es', 'fr', 'it', 'ja', 'ko', 'ru', 'zh-CN', 'zh-TW'];
|
||||
if (product.quality !== 'stable') {
|
||||
systemLanguages.push('hu');
|
||||
}
|
||||
|
||||
export class LocalizationsService extends Disposable implements ILocalizationsService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly cache: LanguagePacksCache;
|
||||
|
||||
private readonly _onDidLanguagesChange: Emitter<void> = this._register(new Emitter<void>());
|
||||
readonly onDidLanguagesChange: Event<void> = this._onDidLanguagesChange.event;
|
||||
|
||||
constructor(
|
||||
@IExtensionManagementService private extensionManagementService: IExtensionManagementService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@ILogService private logService: ILogService
|
||||
) {
|
||||
super();
|
||||
this.cache = this._register(new LanguagePacksCache(environmentService, logService));
|
||||
|
||||
this._register(extensionManagementService.onDidInstallExtension(({ local }) => this.onDidInstallExtension(local)));
|
||||
this._register(extensionManagementService.onDidUninstallExtension(({ identifier }) => this.onDidUninstallExtension(identifier)));
|
||||
|
||||
this.extensionManagementService.getInstalled().then(installed => this.cache.update(installed));
|
||||
}
|
||||
|
||||
getLanguageIds(): TPromise<string[]> {
|
||||
return this.cache.getLanguagePacks()
|
||||
.then(languagePacks => {
|
||||
const languages = [...systemLanguages, ...Object.keys(languagePacks)];
|
||||
return TPromise.as(distinct(languages));
|
||||
});
|
||||
}
|
||||
|
||||
private onDidInstallExtension(extension: ILocalExtension): void {
|
||||
if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.localizations && extension.manifest.contributes.localizations.length) {
|
||||
this.logService.debug('Adding language packs from the extension', extension.identifier.id);
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
private onDidUninstallExtension(identifier: IExtensionIdentifier): void {
|
||||
this.cache.getLanguagePacks()
|
||||
.then(languagePacks => {
|
||||
identifier = { id: getIdFromLocalExtensionId(identifier.id), uuid: identifier.uuid };
|
||||
if (Object.keys(languagePacks).some(language => languagePacks[language] && languagePacks[language].extensions.some(e => areSameExtensions(e.extensionIdentifier, identifier)))) {
|
||||
this.logService.debug('Removing language packs from the extension', identifier.id);
|
||||
this.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
TPromise.join([this.cache.getLanguagePacks(), this.extensionManagementService.getInstalled()])
|
||||
.then(([current, installed]) => this.cache.update(installed)
|
||||
.then(updated => {
|
||||
if (!equals(Object.keys(current), Object.keys(updated))) {
|
||||
this._onDidLanguagesChange.fire();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
class LanguagePacksCache extends Disposable {
|
||||
|
||||
private languagePacks: { [language: string]: ILanguagePack } = {};
|
||||
private languagePacksFilePath: string;
|
||||
private languagePacksFileLimiter: Limiter<void>;
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@ILogService private logService: ILogService
|
||||
) {
|
||||
super();
|
||||
this.languagePacksFilePath = join(environmentService.userDataPath, 'languagepacks.json');
|
||||
this.languagePacksFileLimiter = new Limiter(1);
|
||||
}
|
||||
|
||||
getLanguagePacks(): TPromise<{ [language: string]: ILanguagePack }> {
|
||||
// if queue is not empty, fetch from disk
|
||||
if (this.languagePacksFileLimiter.size) {
|
||||
return this.withLanguagePacks()
|
||||
.then(() => this.languagePacks);
|
||||
}
|
||||
return TPromise.as(this.languagePacks);
|
||||
}
|
||||
|
||||
update(extensions: ILocalExtension[]): TPromise<{ [language: string]: ILanguagePack }> {
|
||||
return this.withLanguagePacks(languagePacks => {
|
||||
Object.keys(languagePacks).forEach(language => languagePacks[language] = undefined);
|
||||
this.createLanguagePacksFromExtensions(languagePacks, ...extensions);
|
||||
}).then(() => this.languagePacks);
|
||||
}
|
||||
|
||||
private createLanguagePacksFromExtensions(languagePacks: { [language: string]: ILanguagePack }, ...extensions: ILocalExtension[]): void {
|
||||
for (const extension of extensions) {
|
||||
if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.localizations && extension.manifest.contributes.localizations.length) {
|
||||
this.createLanguagePacksFromExtension(languagePacks, extension);
|
||||
}
|
||||
}
|
||||
Object.keys(languagePacks).forEach(languageId => this.updateHash(languagePacks[languageId]));
|
||||
}
|
||||
|
||||
private createLanguagePacksFromExtension(languagePacks: { [language: string]: ILanguagePack }, extension: ILocalExtension): void {
|
||||
const extensionIdentifier = { id: getGalleryExtensionIdFromLocal(extension), uuid: extension.identifier.uuid };
|
||||
for (const localizationContribution of extension.manifest.contributes.localizations) {
|
||||
if (isValidLocalization(localizationContribution)) {
|
||||
let languagePack = languagePacks[localizationContribution.languageId];
|
||||
if (!languagePack) {
|
||||
languagePack = { hash: '', extensions: [], translations: {} };
|
||||
languagePacks[localizationContribution.languageId] = languagePack;
|
||||
}
|
||||
let extensionInLanguagePack = languagePack.extensions.filter(e => areSameExtensions(e.extensionIdentifier, extensionIdentifier))[0];
|
||||
if (extensionInLanguagePack) {
|
||||
extensionInLanguagePack.version = extension.manifest.version;
|
||||
} else {
|
||||
languagePack.extensions.push({ extensionIdentifier, version: extension.manifest.version });
|
||||
}
|
||||
for (const translation of localizationContribution.translations) {
|
||||
languagePack.translations[translation.id] = join(extension.path, translation.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private updateHash(languagePack: ILanguagePack): void {
|
||||
if (languagePack) {
|
||||
const md5 = createHash('md5');
|
||||
for (const extension of languagePack.extensions) {
|
||||
md5.update(extension.extensionIdentifier.uuid || extension.extensionIdentifier.id).update(extension.version);
|
||||
}
|
||||
languagePack.hash = md5.digest('hex');
|
||||
}
|
||||
}
|
||||
|
||||
private withLanguagePacks<T>(fn: (languagePacks: { [language: string]: ILanguagePack }) => T = () => null): 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]: ILanguagePack }>(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]) {
|
||||
delete languagePacks[language];
|
||||
}
|
||||
}
|
||||
this.languagePacks = languagePacks;
|
||||
const raw = JSON.stringify(this.languagePacks);
|
||||
this.logService.debug('Writing language packs', raw);
|
||||
return pfs.writeFile(this.languagePacksFilePath, raw);
|
||||
})
|
||||
.then(() => result, error => this.logService.error(error));
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user