diff --git a/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts b/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts index dba266e0852..e1b3643ad8d 100644 --- a/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts +++ b/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts @@ -146,9 +146,6 @@ export class ColorFormatter { constructor(format: string) { this.parse(format); - // this.tree.push(createLiteralNode('new Color(')); - // this.tree.push(createPropertyNode('red', 'd', 0, 255)); - // this.tree.push(createLiteralNode(')')); } private parse(format: string): void { @@ -166,7 +163,7 @@ export class ColorFormatter { // add more parser catches const variable = match[1]; if (!variable) { - throw new Error(`${variable} is not defined`); + throw new Error(`${variable} is not defined.`); } const decimals = parseInt(match[2]); const type = match[3]; diff --git a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts index db6dc3c0cf9..fec7afcd98c 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts @@ -16,7 +16,7 @@ import { wireCancellationToken } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Position as EditorPosition } from 'vs/editor/common/core/position'; import { Range as EditorRange } from 'vs/editor/common/core/range'; -import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape } from '../node/extHost.protocol'; +import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, IRawColorInfo, IColorFormatMap } from '../node/extHost.protocol'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration'; import { IHeapService } from './mainThreadHeapService'; @@ -28,6 +28,7 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape private _heapService: IHeapService; private _modeService: IModeService; private _registrations: { [handle: number]: IDisposable; } = Object.create(null); + private _colorFormatsMap: Map; constructor( @IThreadService threadService: IThreadService, @@ -38,6 +39,7 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape this._proxy = threadService.get(ExtHostContext.ExtHostLanguageFeatures); this._heapService = heapService; this._modeService = modeService; + this._colorFormatsMap = new Map(); } $unregister(handle: number): TPromise { @@ -269,27 +271,17 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape $registerDocumentColorProvider(handle: number, selector: vscode.DocumentSelector): TPromise { const proxy = this._proxy; + const colorFormatsMap = this._colorFormatsMap; + this._registrations[handle] = modes.ColorProviderRegistry.register(selector, { provideColorRanges: function (model, token) { return wireCancellationToken(token, proxy.$provideDocumentColors(handle, model.uri)) .then((colorInfos) => { return colorInfos.map(c => { - let format: modes.IColorFormat; - if (typeof c.format === 'string') { - format = c.format; - } else { - format = { opaque: c.format[0], transparent: c.format[1] }; - } + const format = colorFormatsMap.get(c.format); let availableFormats: modes.IColorFormat[] = []; - c.availableFormats.forEach(format => { - if (typeof format === 'string') { - availableFormats.push(format); - } else { - availableFormats.push({ - opaque: format[0], - transparent: format[1] - }); - } + c.availableFormats.forEach(f => { + availableFormats.push(colorFormatsMap.get(c.format)); }); const [red, green, blue, alpha] = c.color; @@ -313,6 +305,23 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape return undefined; } + $registerColorFormats(formats: IColorFormatMap): TPromise { + formats.forEach(f => { + const raw = f[1]; + let format: modes.IColorFormat; + if (typeof raw === 'string') { + format = raw; + } else { + format = { + opaque: raw[1][0], + transparent: raw[1][0] + }; + } + this._colorFormatsMap.set(f[0], format); + }); + return undefined; + } + // --- configuration $setLanguageConfiguration(handle: number, languageId: string, _configuration: vscode.LanguageConfiguration): TPromise { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 76d6587c559..ac13cb2ae93 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -230,6 +230,7 @@ export abstract class MainThreadLanguageFeaturesShape { $registerSuggestSupport(handle: number, selector: vscode.DocumentSelector, triggerCharacters: string[]): TPromise { throw ni(); } $registerSignatureHelpProvider(handle: number, selector: vscode.DocumentSelector, triggerCharacter: string[]): TPromise { throw ni(); } $registerDocumentLinkProvider(handle: number, selector: vscode.DocumentSelector): TPromise { throw ni(); } + $registerColorFormats(formats: IColorFormatMap): TPromise { throw ni(); } $registerDocumentColorProvider(handle: number, selector: vscode.DocumentSelector): TPromise { throw ni(); } $setLanguageConfiguration(handle: number, languageId: string, configuration: vscode.LanguageConfiguration): TPromise { throw ni(); } } @@ -464,13 +465,16 @@ export namespace ObjectIdentifier { export abstract class ExtHostHeapServiceShape { $onGarbageCollection(ids: number[]): void { throw ni(); } } -export interface IColorInfo { +export interface IRawColorInfo { color: [number, number, number, number | undefined]; - format: string | [string, string]; - availableFormats: (string | [string, string])[]; + format: number; + availableFormats: number[]; range: IRange; } +export type IRawColorFormat = string | [string, string]; +export type IColorFormatMap = [number, IRawColorFormat][]; + export abstract class ExtHostLanguageFeaturesShape { $provideDocumentSymbols(handle: number, resource: URI): TPromise { throw ni(); } $provideCodeLenses(handle: number, resource: URI): TPromise { throw ni(); } @@ -492,7 +496,7 @@ export abstract class ExtHostLanguageFeaturesShape { $resolveCompletionItem(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise { throw ni(); } $provideSignatureHelp(handle: number, resource: URI, position: IPosition): TPromise { throw ni(); } $provideDocumentLinks(handle: number, resource: URI): TPromise { throw ni(); } - $provideDocumentColors(handle: number, resource: URI): TPromise { throw ni(); } + $provideDocumentColors(handle: number, resource: URI): TPromise { throw ni(); } $resolveDocumentLink(handle: number, link: modes.ILink): TPromise { throw ni(); } } diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index dc4c66ad3ba..d442609807b 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -19,7 +19,7 @@ import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHos import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics'; import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search'; import { asWinJsPromise } from 'vs/base/common/async'; -import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IColorInfo } from './extHost.protocol'; +import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IRawColorFormat, IColorFormatMap } from './extHost.protocol'; import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange } from 'vs/editor/common/core/range'; @@ -668,20 +668,51 @@ class LinkProviderAdapter { class ColorProviderAdapter { + private _proxy: MainThreadLanguageFeaturesShape; private _documents: ExtHostDocuments; private _provider: vscode.DocumentColorProvider; + private _formatStorageMap: Map; + private _formatStorageIndex; - constructor(documents: ExtHostDocuments, provider: vscode.DocumentColorProvider) { + constructor(proxy: MainThreadLanguageFeaturesShape, documents: ExtHostDocuments, provider: vscode.DocumentColorProvider) { + this._proxy = proxy; this._documents = documents; this._provider = provider; + this._formatStorageMap = new Map(); + this._formatStorageIndex = 0; } - provideColors(resource: URI): TPromise { + provideColors(resource: URI): TPromise { const doc = this._documents.getDocumentData(resource).document; return asWinJsPromise(token => this._provider.provideDocumentColors(doc, token)).then(colors => { if (Array.isArray(colors)) { - return colors.map(TypeConverters.DocumentColor.from); + const colorFormats: IColorFormatMap = []; + const colorInfos: IRawColorInfo[] = []; + colors.forEach(ci => { + let cachedId = this._formatStorageMap.get(ci.format); + if (cachedId === undefined) { + cachedId = this._formatStorageIndex; + this._formatStorageMap.set(ci.format, cachedId); + this._formatStorageIndex += 1; + + if (typeof ci.format === 'string') { // Append to format list for registration + colorFormats.push([cachedId, ci.format]); + } else { + colorFormats.push([cachedId, [ci.format.opaque, ci.format.transparent]]); + } + } + + colorInfos.push({ + color: [ci.color.red, ci.color.green, ci.color.blue, ci.color.alpha], + format: cachedId, + availableFormats: [], + range: TypeConverters.fromRange(ci.range) + }); + }); + + this._proxy.$registerColorFormats(colorFormats); + return colorInfos; } return undefined; }); @@ -978,12 +1009,12 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable { const handle = this._nextHandle(); - this._adapter.set(handle, new ColorProviderAdapter(this._documents, provider)); + this._adapter.set(handle, new ColorProviderAdapter(this._proxy, this._documents, provider)); this._proxy.$registerDocumentColorProvider(handle, selector); return this._createDisposable(handle); } - $provideDocumentColors(handle: number, resource: URI): TPromise { + $provideDocumentColors(handle: number, resource: URI): TPromise { return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColors(resource)); } diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index 61de4a98d1d..44f7d9da0f8 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -16,7 +16,7 @@ import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange } from 'vs/editor/common/core/range'; import { ISelection } from 'vs/editor/common/core/selection'; -import { IColorInfo } from 'vs/workbench/api/node/extHost.protocol'; +import { IRawColorFormat } from "vs/workbench/api/node/extHost.protocol"; export interface PositionLike { line: number; @@ -370,30 +370,16 @@ export namespace DocumentLink { } } -export namespace DocumentColor { - export function from(colorInfo: vscode.ColorInfo): IColorInfo { +export namespace DocumentColorFormat { + export function from(colorFormat: vscode.IColorFormat): IRawColorFormat { let format: string | [string, string]; - if (typeof colorInfo.format === 'string') { - format = colorInfo.format; + if (typeof colorFormat === 'string') { + format = colorFormat; } else { - format = [colorInfo.format.opaque, colorInfo.format.transparent]; + format = [colorFormat.opaque, colorFormat.transparent]; } - let availableFormats: (string | [string, string])[] = []; - colorInfo.availableFormats.forEach(format => { - if (typeof format === 'string') { - availableFormats.push(format); - } else { - availableFormats.push([format.opaque, format.transparent]); - } - }); - - return { - color: [colorInfo.color.red, colorInfo.color.green, colorInfo.color.blue, colorInfo.color.alpha], - format: format, - availableFormats: availableFormats, - range: fromRange(colorInfo.range) - }; + return format; } }