From 0ba9f6631daec96a2b71eeb337e29f50dd21c7e1 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Wed, 30 Oct 2019 15:51:52 +0100 Subject: [PATCH] Load extension resources using IExtensionResourceLoaderService --- .../languageConfigurationExtensionPoint.ts | 8 ++-- .../contrib/snippets/browser/snippetsFile.ts | 17 +++++++-- .../snippets/browser/snippetsService.ts | 8 ++-- .../snippets/test/browser/snippetFile.test.ts | 2 +- .../browser/extensionResourceLoaderService.ts | 38 +++++++++++++++++++ .../common/extensionResourceLoader.ts | 21 ++++++++++ .../extensionResourceLoaderService.ts | 25 ++++++++++++ .../browser/abstractTextMateService.ts | 9 ++--- .../textMate/browser/textMateService.ts | 6 +-- .../electron-browser/textMateService.ts | 13 +++---- .../themes/browser/workbenchThemeService.ts | 6 ++- .../services/themes/common/colorThemeData.ts | 32 ++++++++-------- src/vs/workbench/workbench.desktop.main.ts | 1 + src/vs/workbench/workbench.web.main.ts | 1 + 14 files changed, 142 insertions(+), 45 deletions(-) create mode 100644 src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts create mode 100644 src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts create mode 100644 src/vs/workbench/services/extensionResourceLoader/electron-browser/extensionResourceLoaderService.ts diff --git a/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts b/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts index f88f42e733d..69ee095045d 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts @@ -12,12 +12,12 @@ import { LanguageIdentifier } from 'vs/editor/common/modes'; import { CharacterPair, CommentRule, FoldingRules, IAutoClosingPair, IAutoClosingPairConditional, IndentationRule, LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IFileService } from 'vs/platform/files/common/files'; import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ITextMateService } from 'vs/workbench/services/textMate/common/textMateService'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; interface IRegExp { pattern: string; @@ -69,7 +69,7 @@ export class LanguageConfigurationFileHandler { constructor( @ITextMateService textMateService: ITextMateService, @IModeService private readonly _modeService: IModeService, - @IFileService private readonly _fileService: IFileService, + @IExtensionResourceLoaderService private readonly _extensionResourceLoaderService: IExtensionResourceLoaderService, @IExtensionService private readonly _extensionService: IExtensionService ) { this._done = []; @@ -98,9 +98,9 @@ export class LanguageConfigurationFileHandler { } private _handleConfigFile(languageIdentifier: LanguageIdentifier, configFileLocation: URI): void { - this._fileService.readFile(configFileLocation).then((contents) => { + this._extensionResourceLoaderService.readExtensionResource(configFileLocation).then((contents) => { const errors: ParseError[] = []; - let configuration = parse(contents.value.toString(), errors); + let configuration = parse(contents, errors); if (errors.length) { console.error(nls.localize('parseErrors', "Errors parsing {0}: {1}", configFileLocation.toString(), errors.map(e => (`[${e.offset}, ${e.length}] ${getParseErrorMessage(e.error)}`)).join('\n'))); } diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts b/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts index 5b655286083..b1deb3354ba 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts @@ -14,6 +14,7 @@ import { URI } from 'vs/base/common/uri'; import { IFileService } from 'vs/platform/files/common/files'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IdleValue } from 'vs/base/common/async'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; class SnippetBodyInsights { @@ -153,7 +154,8 @@ export class SnippetFile { readonly location: URI, public defaultScopes: string[] | undefined, private readonly _extension: IExtensionDescription | undefined, - private readonly _fileService: IFileService + private readonly _fileService: IFileService, + private readonly _extensionResourceLoaderService: IExtensionResourceLoaderService ) { this.isGlobalSnippets = extname(location.path) === '.code-snippets'; this.isUserSnippets = !this._extension; @@ -199,10 +201,19 @@ export class SnippetFile { } } + private async _load(): Promise { + if (this._extension) { + return this._extensionResourceLoaderService.readExtensionResource(this.location); + } else { + const content = await this._fileService.readFile(this.location); + return content.value.toString(); + } + } + load(): Promise { if (!this._loadPromise) { - this._loadPromise = Promise.resolve(this._fileService.readFile(this.location)).then(content => { - const data = jsonParse(content.value.toString()); + this._loadPromise = Promise.resolve(this._load()).then(content => { + const data = jsonParse(content); if (getNodeType(data) === 'object') { forEach(data, entry => { const { key: name, value: scopeOrTemplate } = entry; diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts index 241f485ed28..21a1107e650 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts @@ -25,6 +25,7 @@ import { Snippet, SnippetFile, SnippetSource } from 'vs/workbench/contrib/snippe import { ExtensionsRegistry, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { languagesExtPoint } from 'vs/workbench/services/mode/common/workbenchModeService'; import { SnippetCompletionProvider } from './snippetCompletionProvider'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; namespace snippetExt { @@ -139,6 +140,7 @@ class SnippetsService implements ISnippetsService { @IModeService private readonly _modeService: IModeService, @ILogService private readonly _logService: ILogService, @IFileService private readonly _fileService: IFileService, + @IExtensionResourceLoaderService private readonly _extensionResourceLoaderService: IExtensionResourceLoaderService, @ILifecycleService lifecycleService: ILifecycleService, ) { this._pendingWork.push(Promise.resolve(lifecycleService.when(LifecyclePhase.Restored).then(() => { @@ -225,7 +227,7 @@ class SnippetsService implements ISnippetsService { file.defaultScopes = []; } } else { - const file = new SnippetFile(SnippetSource.Extension, validContribution.location, validContribution.language ? [validContribution.language] : undefined, extension.description, this._fileService); + const file = new SnippetFile(SnippetSource.Extension, validContribution.location, validContribution.language ? [validContribution.language] : undefined, extension.description, this._fileService, this._extensionResourceLoaderService); this._files.set(file.location.toString(), file); if (this._environmentService.isExtensionDevelopment) { @@ -318,9 +320,9 @@ class SnippetsService implements ISnippetsService { const key = uri.toString(); if (source === SnippetSource.User && ext === '.json') { const langName = resources.basename(uri).replace(/\.json/, ''); - this._files.set(key, new SnippetFile(source, uri, [langName], undefined, this._fileService)); + this._files.set(key, new SnippetFile(source, uri, [langName], undefined, this._fileService, this._extensionResourceLoaderService)); } else if (ext === '.code-snippets') { - this._files.set(key, new SnippetFile(source, uri, undefined, undefined, this._fileService)); + this._files.set(key, new SnippetFile(source, uri, undefined, undefined, this._fileService, this._extensionResourceLoaderService)); } return { dispose: () => this._files.delete(key) diff --git a/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts b/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts index 83c1292c0a6..a804f261f37 100644 --- a/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts +++ b/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts @@ -11,7 +11,7 @@ suite('Snippets', function () { class TestSnippetFile extends SnippetFile { constructor(filepath: URI, snippets: Snippet[]) { - super(SnippetSource.Extension, filepath, undefined, undefined, undefined!); + super(SnippetSource.Extension, filepath, undefined, undefined, undefined!, undefined!); this.data.push(...snippets); } } diff --git a/src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts b/src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts new file mode 100644 index 00000000000..f2d816cca9e --- /dev/null +++ b/src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { URI } from 'vs/base/common/uri'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; +import * as dom from 'vs/base/browser/dom'; +import { Schemas } from 'vs/base/common/network'; + +class ExtensionResourceLoaderService implements IExtensionResourceLoaderService { + + _serviceBrand: undefined; + + constructor( + @IFileService private readonly _fileService: IFileService + ) { } + + async readExtensionResource(uri: URI): Promise { + uri = dom.asDomUri(uri); + + if (uri.scheme !== Schemas.http && uri.scheme !== Schemas.https) { + const result = await this._fileService.readFile(uri); + return result.value.toString(); + } + + const response = await fetch(uri.toString(true)); + if (response.status !== 200) { + throw new Error(response.statusText); + } + return response.text(); + + } +} + +registerSingleton(IExtensionResourceLoaderService, ExtensionResourceLoaderService); diff --git a/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts b/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts new file mode 100644 index 00000000000..300a54b0842 --- /dev/null +++ b/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { URI } from 'vs/base/common/uri'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const IExtensionResourceLoaderService = createDecorator('extensionResourceLoaderService'); + +/** + * A service useful for reading resources from within extensions. + */ +export interface IExtensionResourceLoaderService { + _serviceBrand: undefined; + + /** + * Read a certain resource within an extension. + */ + readExtensionResource(uri: URI): Promise; +} diff --git a/src/vs/workbench/services/extensionResourceLoader/electron-browser/extensionResourceLoaderService.ts b/src/vs/workbench/services/extensionResourceLoader/electron-browser/extensionResourceLoaderService.ts new file mode 100644 index 00000000000..2acf10e0b53 --- /dev/null +++ b/src/vs/workbench/services/extensionResourceLoader/electron-browser/extensionResourceLoaderService.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { URI } from 'vs/base/common/uri'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; + +class ExtensionResourceLoaderService implements IExtensionResourceLoaderService { + + _serviceBrand: undefined; + + constructor( + @IFileService private readonly _fileService: IFileService + ) { } + + async readExtensionResource(uri: URI): Promise { + const result = await this._fileService.readFile(uri); + return result.value.toString(); + } +} + +registerSingleton(IExtensionResourceLoaderService, ExtensionResourceLoaderService); diff --git a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts index 0fb7101230f..cb553b6fcc8 100644 --- a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts +++ b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts @@ -16,7 +16,6 @@ import { IState, ITokenizationSupport, LanguageId, TokenMetadata, TokenizationRe import { nullTokenize2 } from 'vs/editor/common/modes/nullMode'; import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/tokenization'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; @@ -29,6 +28,7 @@ import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IValidGrammarDefinition, IValidEmbeddedLanguagesMap, IValidTokenTypeMap } from 'vs/workbench/services/textMate/common/TMScopeRegistry'; import { TMGrammarFactory } from 'vs/workbench/services/textMate/common/TMGrammarFactory'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; export abstract class AbstractTextMateService extends Disposable implements ITextMateService { public _serviceBrand: undefined; @@ -48,7 +48,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex constructor( @IModeService private readonly _modeService: IModeService, @IWorkbenchThemeService private readonly _themeService: IWorkbenchThemeService, - @IFileService protected readonly _fileService: IFileService, + @IExtensionResourceLoaderService protected readonly _extensionResourceLoaderService: IExtensionResourceLoaderService, @INotificationService private readonly _notificationService: INotificationService, @ILogService private readonly _logService: ILogService, @IConfigurationService private readonly _configurationService: IConfigurationService, @@ -191,10 +191,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex this._grammarFactory = new TMGrammarFactory({ logTrace: (msg: string) => this._logService.trace(msg), logError: (msg: string, err: any) => this._logService.error(msg, err), - readFile: async (resource: URI) => { - const content = await this._fileService.readFile(resource); - return content.value.toString(); - } + readFile: (resource: URI) => this._extensionResourceLoaderService.readExtensionResource(resource) }, this._grammarDefinitions || [], vscodeTextmate, this._loadOnigLib()); this._onDidCreateGrammarFactory(this._grammarDefinitions || []); diff --git a/src/vs/workbench/services/textMate/browser/textMateService.ts b/src/vs/workbench/services/textMate/browser/textMateService.ts index 8fb8d84099c..9c644998d00 100644 --- a/src/vs/workbench/services/textMate/browser/textMateService.ts +++ b/src/vs/workbench/services/textMate/browser/textMateService.ts @@ -8,25 +8,25 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { AbstractTextMateService } from 'vs/workbench/services/textMate/browser/abstractTextMateService'; import { IOnigLib } from 'vscode-textmate'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; export class TextMateService extends AbstractTextMateService { constructor( @IModeService modeService: IModeService, @IWorkbenchThemeService themeService: IWorkbenchThemeService, - @IFileService fileService: IFileService, + @IExtensionResourceLoaderService extensionResourceLoaderService: IExtensionResourceLoaderService, @INotificationService notificationService: INotificationService, @ILogService logService: ILogService, @IConfigurationService configurationService: IConfigurationService, @IStorageService storageService: IStorageService ) { - super(modeService, themeService, fileService, notificationService, logService, configurationService, storageService); + super(modeService, themeService, extensionResourceLoaderService, notificationService, logService, configurationService, storageService); } protected _loadVSCodeTextmate(): Promise { diff --git a/src/vs/workbench/services/textMate/electron-browser/textMateService.ts b/src/vs/workbench/services/textMate/electron-browser/textMateService.ts index dc35917e961..6a4a4d4d2e2 100644 --- a/src/vs/workbench/services/textMate/electron-browser/textMateService.ts +++ b/src/vs/workbench/services/textMate/electron-browser/textMateService.ts @@ -8,7 +8,6 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { AbstractTextMateService } from 'vs/workbench/services/textMate/browser/abstractTextMateService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { IFileService } from 'vs/platform/files/common/files'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ILogService } from 'vs/platform/log/common/log'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -24,6 +23,7 @@ import { MultilineTokensBuilder } from 'vs/editor/common/model/tokensStore'; import { TMGrammarFactory } from 'vs/workbench/services/textMate/common/TMGrammarFactory'; import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents'; import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; const RUN_TEXTMATE_IN_WORKER = false; @@ -117,14 +117,13 @@ export class TextMateWorkerHost { constructor( private readonly textMateService: TextMateService, - @IFileService private readonly _fileService: IFileService + @IExtensionResourceLoaderService private readonly _extensionResourceLoaderService: IExtensionResourceLoaderService, ) { } async readFile(_resource: UriComponents): Promise { const resource = URI.revive(_resource); - const content = await this._fileService.readFile(resource); - return content.value.toString(); + return this._extensionResourceLoaderService.readExtensionResource(resource); } async setTokens(_resource: UriComponents, versionId: number, tokens: Uint8Array): Promise { @@ -142,14 +141,14 @@ export class TextMateService extends AbstractTextMateService { constructor( @IModeService modeService: IModeService, @IWorkbenchThemeService themeService: IWorkbenchThemeService, - @IFileService fileService: IFileService, + @IExtensionResourceLoaderService extensionResourceLoaderService: IExtensionResourceLoaderService, @INotificationService notificationService: INotificationService, @ILogService logService: ILogService, @IConfigurationService configurationService: IConfigurationService, @IStorageService storageService: IStorageService, @IModelService private readonly _modelService: IModelService, ) { - super(modeService, themeService, fileService, notificationService, logService, configurationService, storageService); + super(modeService, themeService, extensionResourceLoaderService, notificationService, logService, configurationService, storageService); this._worker = null; this._workerProxy = null; this._tokenizers = Object.create(null); @@ -190,7 +189,7 @@ export class TextMateService extends AbstractTextMateService { this._killWorker(); if (RUN_TEXTMATE_IN_WORKER) { - const workerHost = new TextMateWorkerHost(this, this._fileService); + const workerHost = new TextMateWorkerHost(this, this._extensionResourceLoaderService); const worker = createWebWorker(this._modelService, { createData: { grammarDefinitions diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index db39fb64c64..85b09406b2c 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -32,6 +32,7 @@ import { workbenchColorsSchemaId } from 'vs/platform/theme/common/colorRegistry' import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; // implementation @@ -98,6 +99,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { @ITelemetryService private readonly telemetryService: ITelemetryService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @IFileService private readonly fileService: IFileService, + @IExtensionResourceLoaderService private readonly extensionResourceLoaderService: IExtensionResourceLoaderService, @IWorkbenchLayoutService readonly layoutService: IWorkbenchLayoutService ) { @@ -341,7 +343,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return null; } const themeData = data; - return themeData.ensureLoaded(this.fileService).then(_ => { + return themeData.ensureLoaded(this.extensionResourceLoaderService).then(_ => { if (themeId === this.currentColorTheme.id && !this.currentColorTheme.isLoaded && this.currentColorTheme.hasEqualData(themeData)) { // the loaded theme is identical to the perisisted theme. Don't need to send an event. this.currentColorTheme = themeData; @@ -360,7 +362,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } private async reloadCurrentColorTheme() { - await this.currentColorTheme.reload(this.fileService); + await this.currentColorTheme.reload(this.extensionResourceLoaderService); this.currentColorTheme.setCustomColors(this.colorCustomizations); this.currentColorTheme.setCustomTokenColors(this.tokenColorCustomizations); this.updateDynamicCSSRules(this.currentColorTheme); diff --git a/src/vs/workbench/services/themes/common/colorThemeData.ts b/src/vs/workbench/services/themes/common/colorThemeData.ts index 681815443ec..df2006b67c8 100644 --- a/src/vs/workbench/services/themes/common/colorThemeData.ts +++ b/src/vs/workbench/services/themes/common/colorThemeData.ts @@ -17,9 +17,9 @@ import { ThemeType } from 'vs/platform/theme/common/themeService'; import { Registry } from 'vs/platform/registry/common/platform'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; import { URI } from 'vs/base/common/uri'; -import { IFileService } from 'vs/platform/files/common/files'; import { parse as parsePList } from 'vs/workbench/services/themes/common/plistParser'; import { startsWith } from 'vs/base/common/strings'; +import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; let colorRegistry = Registry.as(Extensions.ColorContribution); @@ -167,21 +167,21 @@ export class ColorThemeData implements IColorTheme { } } - public ensureLoaded(fileService: IFileService): Promise { - return !this.isLoaded ? this.load(fileService) : Promise.resolve(undefined); + public ensureLoaded(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise { + return !this.isLoaded ? this.load(extensionResourceLoaderService) : Promise.resolve(undefined); } - public reload(fileService: IFileService): Promise { - return this.load(fileService); + public reload(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise { + return this.load(extensionResourceLoaderService); } - private load(fileService: IFileService): Promise { + private load(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise { if (!this.location) { return Promise.resolve(undefined); } this.themeTokenColors = []; this.colorMap = {}; - return _loadColorTheme(fileService, this.location, this.themeTokenColors, this.colorMap).then(_ => { + return _loadColorTheme(extensionResourceLoaderService, this.location, this.themeTokenColors, this.colorMap).then(_ => { this.isLoaded = true; }); } @@ -295,11 +295,11 @@ function toCSSSelector(extensionId: string, path: string) { return str; } -function _loadColorTheme(fileService: IFileService, themeLocation: URI, resultRules: ITokenColorizationRule[], resultColors: IColorMap): Promise { +function _loadColorTheme(extensionResourceLoaderService: IExtensionResourceLoaderService, themeLocation: URI, resultRules: ITokenColorizationRule[], resultColors: IColorMap): Promise { if (resources.extname(themeLocation) === '.json') { - return fileService.readFile(themeLocation).then(content => { + return extensionResourceLoaderService.readExtensionResource(themeLocation).then(content => { let errors: Json.ParseError[] = []; - let contentValue = Json.parse(content.value.toString(), errors); + let contentValue = Json.parse(content, errors); if (errors.length > 0) { return Promise.reject(new Error(nls.localize('error.cannotparsejson', "Problems parsing JSON theme file: {0}", errors.map(e => getParseErrorMessage(e.error)).join(', ')))); } else if (Json.getNodeType(contentValue) !== 'object') { @@ -307,7 +307,7 @@ function _loadColorTheme(fileService: IFileService, themeLocation: URI, resultRu } let includeCompletes: Promise = Promise.resolve(null); if (contentValue.include) { - includeCompletes = _loadColorTheme(fileService, resources.joinPath(resources.dirname(themeLocation), contentValue.include), resultRules, resultColors); + includeCompletes = _loadColorTheme(extensionResourceLoaderService, resources.joinPath(resources.dirname(themeLocation), contentValue.include), resultRules, resultColors); } return includeCompletes.then(_ => { if (Array.isArray(contentValue.settings)) { @@ -333,7 +333,7 @@ function _loadColorTheme(fileService: IFileService, themeLocation: URI, resultRu resultRules.push(...tokenColors); return null; } else if (typeof tokenColors === 'string') { - return _loadSyntaxTokens(fileService, resources.joinPath(resources.dirname(themeLocation), tokenColors), resultRules, {}); + return _loadSyntaxTokens(extensionResourceLoaderService, resources.joinPath(resources.dirname(themeLocation), tokenColors), resultRules, {}); } else { return Promise.reject(new Error(nls.localize({ key: 'error.invalidformat.tokenColors', comment: ['{0} will be replaced by a path. Values in quotes should not be translated.'] }, "Problem parsing color theme file: {0}. Property 'tokenColors' should be either an array specifying colors or a path to a TextMate theme file", themeLocation.toString()))); } @@ -342,14 +342,14 @@ function _loadColorTheme(fileService: IFileService, themeLocation: URI, resultRu }); }); } else { - return _loadSyntaxTokens(fileService, themeLocation, resultRules, resultColors); + return _loadSyntaxTokens(extensionResourceLoaderService, themeLocation, resultRules, resultColors); } } -function _loadSyntaxTokens(fileService: IFileService, themeLocation: URI, resultRules: ITokenColorizationRule[], resultColors: IColorMap): Promise { - return fileService.readFile(themeLocation).then(content => { +function _loadSyntaxTokens(extensionResourceLoaderService: IExtensionResourceLoaderService, themeLocation: URI, resultRules: ITokenColorizationRule[], resultColors: IColorMap): Promise { + return extensionResourceLoaderService.readExtensionResource(themeLocation).then(content => { try { - let contentValue = parsePList(content.value.toString()); + let contentValue = parsePList(content); let settings: ITokenColorizationRule[] = contentValue.settings; if (!Array.isArray(settings)) { return Promise.reject(new Error(nls.localize('error.plist.invalidformat', "Problem parsing tmTheme file: {0}. 'settings' is not array."))); diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 18980940dfb..460c38ba63a 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -61,6 +61,7 @@ import 'vs/workbench/services/clipboard/electron-browser/clipboardService'; import 'vs/workbench/services/update/electron-browser/updateService'; import 'vs/workbench/services/issue/electron-browser/issueService'; import 'vs/workbench/services/menubar/electron-browser/menubarService'; +import 'vs/workbench/services/extensionResourceLoader/electron-browser/extensionResourceLoaderService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index fa08843395f..bed3663cfcb 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -48,6 +48,7 @@ import 'vs/workbench/services/host/browser/browserHostService'; import 'vs/workbench/services/request/browser/requestService'; import 'vs/workbench/services/lifecycle/browser/lifecycleService'; import 'vs/workbench/services/clipboard/browser/clipboardService'; +import 'vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; -- GitLab