diff --git a/Documentation/LanguageServer/colorization.md b/Documentation/LanguageServer/colorization.md index 595d846a2..49ef83d96 100644 --- a/Documentation/LanguageServer/colorization.md +++ b/Documentation/LanguageServer/colorization.md @@ -19,32 +19,32 @@ Colors are associated with [TextMate scopes](https://macromates.com/manual/en/la | Token | Scope | | ------------- |:-------------:| -| Class Template | entity.name.class.template | +| Class Template | entity.name.type.class.templated | | Enumerator | variable.other.enummember | | Event (C++/CLI) | variable.other.event | | Function | entity.name.function | -| Function Template | entity.name.function.template | -| Generic Type (C++/CLI) | entity.name.class.generic | +| Function Template | entity.name.function.templated | +| Generic Type (C++/CLI) | entity.name.type.class.generic | | Global Variable | variable.other.global | | Label | entity.name.label | | Local Variable | variable.other.local | | Macro | entity.name.function.preprocessor | -| Member Field | variable.other.member | +| Member Field | variable.other.property | | Member Function | entity.name.function.member | -| Member Operator | keyword.operator.member | -| Namespace | entity.name.type.namespace | +| Namespace | entity.name.namespace | | New / Delete | keyword.operator.new | -| Operator Function | entity.name.function.operator | +| Operator Overload Function | entity.name.function.operator | +| Operator Overload Member | entity.name.function.operator.member | | Parameter | variable.parameter | -| Property (C++/CLI) | variable.other.property | -| Reference Type (C++/CLI) | entity.name.class.reference | -| Static Member Field | variable.other.member.static | +| Property (C++/CLI) | variable.other.property.cli | +| Reference Type (C++/CLI) | entity.name.type.class.reference | +| Static Member Field | variable.other.property.static | | Static Member Function | entity.name.function.member.static | -| Type | entity.name.type | -| User-Defined Literal - Number | entity.name.user-defined-literal.number | -| User-Defined Literal - Raw | entity.name.user-defined-literal | -| User-Defined Literal - String | entity.name.user-defined-literal.string | -| Value Type (C++/CLI) | entity.name.class.value | +| Type | entity.name.type.class | +| User-Defined Literal - Number | entity.name.operator.custom-literal.number | +| User-Defined Literal - Raw | entity.name.operator.custom-literal | +| User-Defined Literal - String | entity.name.operator.custom-literal.string | +| Value Type (C++/CLI) | entity.name.type.class.value | Many of the tokens recognized by IntelliSense do not directly map to existing scopes in the VS Code's default C/C++ TextMate grammar, so are likely not colored by existing VS Code themes. @@ -55,7 +55,7 @@ Colors can also be overridden globally, in settings: "editor.tokenColorCustomizations": { "textMateRules": [ { - "scope": "entity.name.type", + "scope": "entity.name.type.class", "settings": { "foreground": "#FF0000", "fontStyle": "italic bold underline" @@ -70,7 +70,7 @@ Or, overridden on a per-theme basis: "[Visual Studio Dark]": { "textMateRules": [ { - "scope": "entity.name.type", + "scope": "entity.name.type.class", "settings": { "foreground": "#FF0000", "fontStyle": "italic bold underline" @@ -171,19 +171,19 @@ Use the following to augment the Visual Studio Dark theme to match what Visual S } }, { - "scope": "entity.name.type", + "scope": "entity.name.type.class", "settings": { "foreground": "#4EC9B0" } }, { - "scope": "entity.name.class.reference", + "scope": "entity.name.type.class.reference", "settings": { "foreground": "#4EC9B0" } }, { - "scope": "entity.name.class.value", + "scope": "entity.name.type.class.value", "settings": { "foreground": "#4EC9B0" } @@ -201,7 +201,7 @@ Use the following to augment the Visual Studio Dark theme to match what Visual S } }, { - "scope": "variable.other.member", + "scope": "variable.other.property", "settings": { "foreground": "#DADADA" } @@ -213,7 +213,7 @@ Use the following to augment the Visual Studio Dark theme to match what Visual S } }, { - "scope": "variable.other.member.static", + "scope": "variable.other.property.static", "settings": { "foreground": "#C8C8C8" } @@ -225,19 +225,19 @@ Use the following to augment the Visual Studio Dark theme to match what Visual S } }, { - "scope": "entity.name.class.template", + "scope": "entity.name.type.class.templated", "settings": { "foreground": "#4EC9B0" } }, { - "scope": "entity.name.class.generic", + "scope": "entity.name.type.class.generic", "settings": { "foreground": "#4EC9B0" } }, { - "scope": "entity.name.function.template", + "scope": "entity.name.function.templated", "settings": { "foreground": "#C8C8C8" } @@ -255,19 +255,19 @@ Use the following to augment the Visual Studio Dark theme to match what Visual S } }, { - "scope": "entity.name.user-defined-literal", + "scope": "entity.name.operator.custom-literal", "settings": { "foreground": "#DADADA" } }, { - "scope": "entity.name.user-defined-literal.string", + "scope": "entity.name.operator.custom-literal.string", "settings": { "foreground": "#D69D85" } }, { - "scope": "entity.name.user-defined-literal.number", + "scope": "entity.name.operator.custom-literal.number", "settings": { "foreground": "#B5CEA8" } @@ -386,19 +386,19 @@ Use the following to augment the Visual Studio Light theme to match what Visual } }, { - "scope": "entity.name.type", + "scope": "entity.name.type.class", "settings": { "foreground": "#2B91AF" } }, { - "scope": "entity.name.class.reference", + "scope": "entity.name.type.class.reference", "settings": { "foreground": "#2B91AF" } }, { - "scope": "entity.name.class.value", + "scope": "entity.name.type.class.value", "settings": { "foreground": "#2B91AF" } @@ -416,7 +416,7 @@ Use the following to augment the Visual Studio Light theme to match what Visual } }, { - "scope": "variable.other.member", + "scope": "variable.other.property", "settings": { "foreground": "#000000" } @@ -428,7 +428,7 @@ Use the following to augment the Visual Studio Light theme to match what Visual } }, { - "scope": "variable.other.member.static", + "scope": "variable.other.property.static", "settings": { "foreground": "#000000" } @@ -440,19 +440,19 @@ Use the following to augment the Visual Studio Light theme to match what Visual } }, { - "scope": "entity.name.class.template", + "scope": "entity.name.type.class.templated", "settings": { "foreground": "#2B91AF" } }, { - "scope": "entity.name.class.generic", + "scope": "entity.name.type.class.generic", "settings": { "foreground": "#2B91AF" } }, { - "scope": "entity.name.function.template", + "scope": "entity.name.function.templated", "settings": { "foreground": "#000000" } @@ -470,19 +470,19 @@ Use the following to augment the Visual Studio Light theme to match what Visual } }, { - "scope": "entity.name.user-defined-literal", + "scope": "entity.name.operator.custom-literal", "settings": { "foreground": "#000000" } }, { - "scope": "entity.name.user-defined-literal.string", + "scope": "entity.name.operator.custom-literal.string", "settings": { "foreground": "#A31515" } }, { - "scope": "entity.name.user-defined-literal.number", + "scope": "entity.name.operator.custom-literal.number", "settings": { "foreground": "#000000" } diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index dacc0e309..418ce7c8d 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,5 +1,10 @@ # C/C++ for Visual Studio Code Change Log +## Version 0.24.1: July 22, 2019 +### Bug Fixes +* Fix an issue with the Outline not being populated when a file is opened. [#3877](https://github.com/microsoft/vscode-cpptools/issues/3877) +* Update scopes used by semantic colorization. [PR# 3896](https://github.com/microsoft/vscode-cpptools/pull/3896) + ## Version 0.24.0: July 3, 2019 ### New Features * Semantic colorization [Documentation](https://github.com/microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/colorization.md) [#230](https://github.com/microsoft/vscode-cpptools/issues/230) diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index e7ee88eae..fb838d3f3 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -786,75 +786,76 @@ class DefaultClient implements Client { } public async provideCustomConfiguration(document: vscode.TextDocument): Promise { - let tokenSource: CancellationTokenSource = new CancellationTokenSource(); - let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); - if (providers.size === 0) { - return Promise.resolve(); - } - console.log("provideCustomConfiguration"); - let providerId: string|undefined = await this.getCustomConfigurationProviderId(); - if (!providerId) { - return Promise.resolve(); - } + return this.queueBlockingTask(async () => { + let tokenSource: CancellationTokenSource = new CancellationTokenSource(); + let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); + if (providers.size === 0) { + return Promise.resolve(); + } + console.log("provideCustomConfiguration"); + let providerId: string|undefined = this.configuration.CurrentConfigurationProvider; + if (!providerId) { + return Promise.resolve(); + } - let providerName: string = providerId; - let params: QueryTranslationUnitSourceParams = { - uri: document.uri.toString() - }; - let response: QueryTranslationUnitSourceResult = await this.requestWhenReady(() => this.languageClient.sendRequest(QueryTranslationUnitSourceRequest, params)); - if (response.configDisposition === QueryTranslationUnitSourceConfigDisposition.ConfigNotNeeded) { - return Promise.resolve(); - } + let providerName: string = providerId; + let params: QueryTranslationUnitSourceParams = { + uri: document.uri.toString() + }; + let response: QueryTranslationUnitSourceResult = await this.languageClient.sendRequest(QueryTranslationUnitSourceRequest, params); + if (response.configDisposition === QueryTranslationUnitSourceConfigDisposition.ConfigNotNeeded) { + return Promise.resolve(); + } - let tuUri: vscode.Uri = vscode.Uri.parse(response.uri); - let configName: string = await this.getCurrentConfigName(); - const notReadyMessage: string = `${providerName} is not ready`; - let provideConfigurationAsync: () => Thenable = async () => { - // The config requests that we use a provider, try to get IntelliSense configuration info from that provider. - try { - let provider: CustomConfigurationProvider1|null = providers.get(providerId); - if (provider) { - if (!provider.isReady) { - return Promise.reject(notReadyMessage); - } + let tuUri: vscode.Uri = vscode.Uri.parse(response.uri); + let configName: string = this.configuration.CurrentConfiguration.name; + const notReadyMessage: string = `${providerName} is not ready`; + let provideConfigurationAsync: () => Thenable = async () => { + // The config requests that we use a provider, try to get IntelliSense configuration info from that provider. + try { + let provider: CustomConfigurationProvider1|null = providers.get(providerId); + if (provider) { + if (!provider.isReady) { + return Promise.reject(notReadyMessage); + } - providerName = provider.name; - if (await provider.canProvideConfiguration(tuUri, tokenSource.token)) { - return provider.provideConfigurations([tuUri], tokenSource.token); + providerName = provider.name; + if (await provider.canProvideConfiguration(tuUri, tokenSource.token)) { + return provider.provideConfigurations([tuUri], tokenSource.token); + } } + } catch (err) { } - } catch (err) { - } - console.warn("failed to provide configuration"); - return Promise.reject(""); - }; + console.warn("failed to provide configuration"); + return Promise.reject(""); + }; - return this.queueTaskWithTimeout(provideConfigurationAsync, configProviderTimeout, tokenSource).then( - (configs: SourceFileConfigurationItem[]) => { - if (configs && configs.length > 0) { - this.sendCustomConfigurations(configs, true); - if (response.configDisposition === QueryTranslationUnitSourceConfigDisposition.AncestorConfigNeeded) { - // replacing uri with original uri - let newConfig: SourceFileConfigurationItem = { uri: document.uri, configuration: configs[0].configuration }; - this.sendCustomConfigurations([newConfig], true); + return this.callTaskWithTimeout(provideConfigurationAsync, configProviderTimeout, tokenSource).then( + (configs: SourceFileConfigurationItem[]) => { + if (configs && configs.length > 0) { + this.sendCustomConfigurations(configs, false); + if (response.configDisposition === QueryTranslationUnitSourceConfigDisposition.AncestorConfigNeeded) { + // replacing uri with original uri + let newConfig: SourceFileConfigurationItem = { uri: document.uri, configuration: configs[0].configuration }; + this.sendCustomConfigurations([newConfig], false); + } } - } - }, - (err) => { - if (err === notReadyMessage) { - return; - } - let settings: CppSettings = new CppSettings(this.RootUri); - if (settings.configurationWarnings === "Enabled" && !this.isExternalHeader(document.uri) && !vscode.debug.activeDebugSession) { - const dismiss: string = "Dismiss"; - const disable: string = "Disable Warnings"; - let message: string = `'${providerName}' is unable to provide IntelliSense configuration information for '${document.uri.fsPath}'. ` + - `Settings from the '${configName}' configuration will be used instead.`; - if (err) { - message += ` (${err})`; + }, + (err) => { + if (err === notReadyMessage) { + return; } + let settings: CppSettings = new CppSettings(this.RootUri); + if (settings.configurationWarnings === "Enabled" && !this.isExternalHeader(document.uri) && !vscode.debug.activeDebugSession) { + const dismiss: string = "Dismiss"; + const disable: string = "Disable Warnings"; + let message: string = `'${providerName}' is unable to provide IntelliSense configuration information for '${document.uri.fsPath}'. ` + + `Settings from the '${configName}' configuration will be used instead.`; + if (err) { + message += ` (${err})`; + } - vscode.window.showInformationMessage(message, dismiss, disable).then(response => { + vscode.window.showInformationMessage(message, dismiss, disable).then(response => { switch (response) { case disable: { settings.toggleSetting("configurationWarnings", "Enabled", "Disabled"); @@ -862,18 +863,15 @@ class DefaultClient implements Client { } } }); - } - }); + } + }); + }); } private isExternalHeader(uri: vscode.Uri): boolean { return util.isHeader(uri) && !uri.toString().startsWith(this.RootUri.toString()); } - private getCustomConfigurationProviderId(): Thenable { - return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfigurationProvider)); - } - public getCurrentConfigName(): Thenable { return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfiguration.name)); } @@ -923,7 +921,7 @@ class DefaultClient implements Client { if (this.pendingTask && !this.pendingTask.Done) { // We don't want the queue to stall because of a rejected promise. - return this.pendingTask.then(nextTask, nextTask); + return this.pendingTask.getPromise().then(nextTask, nextTask); } else { this.pendingTask = undefined; return nextTask(); @@ -941,6 +939,7 @@ class DefaultClient implements Client { private queueBlockingTask(task: () => Thenable): Thenable { if (this.isSupported) { this.pendingTask = new util.BlockingTask(task, this.pendingTask); + return this.pendingTask.getPromise(); } else { return Promise.reject("Unsupported client"); } @@ -973,6 +972,31 @@ class DefaultClient implements Client { }); } + private callTaskWithTimeout(task: () => Thenable, ms: number, cancelToken?: CancellationTokenSource): Thenable { + let timer: NodeJS.Timer; + // Create a promise that rejects in milliseconds + let timeout: () => Promise = () => new Promise((resolve, reject) => { + timer = setTimeout(() => { + clearTimeout(timer); + if (cancelToken) { + cancelToken.cancel(); + } + reject("Timed out in " + ms + "ms."); + }, ms); + }); + + // Returns a race between our timeout and the passed in promise + return Promise.race([task(), timeout()]).then( + (result: any) => { + clearTimeout(timer); + return result; + }, + (error: any) => { + clearTimeout(timer); + throw error; + }); + } + public requestWhenReady(request: () => Thenable): Thenable { return this.queueTask(request); } diff --git a/Extension/src/LanguageServer/colorization.ts b/Extension/src/LanguageServer/colorization.ts index 1d006b125..fc1d5f703 100644 --- a/Extension/src/LanguageServer/colorization.ts +++ b/Extension/src/LanguageServer/colorization.ts @@ -213,26 +213,26 @@ export class ColorizationSettings { this.calculateStyleForToken(TokenKind.GlobalVariable, "variable.other.global", themeName, textMateRules); this.calculateStyleForToken(TokenKind.LocalVariable, "variable.other.local", themeName, textMateRules); this.calculateStyleForToken(TokenKind.Parameter, "variable.parameter", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Type, "entity.name.type", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.RefType, "entity.name.class.reference", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.ValueType, "entity.name.class.value", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.Type, "entity.name.type.class", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.RefType, "entity.name.type.class.reference", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.ValueType, "entity.name.type.class.value", themeName, textMateRules); this.calculateStyleForToken(TokenKind.Function, "entity.name.function", themeName, textMateRules); this.calculateStyleForToken(TokenKind.MemberFunction, "entity.name.function.member", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.MemberField, "variable.other.member", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.MemberField, "variable.other.property", themeName, textMateRules); this.calculateStyleForToken(TokenKind.StaticMemberFunction, "entity.name.function.member.static", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.StaticMemberField, "variable.other.member.static", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Property, "variable.other.property", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.StaticMemberField, "variable.other.property.static", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.Property, "variable.other.property.cli", themeName, textMateRules); this.calculateStyleForToken(TokenKind.Event, "variable.other.event", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.ClassTemplate, "entity.name.class.template", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.GenericType, "entity.name.class.generic", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.FunctionTemplate, "entity.name.function.template", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Namespace, "entity.name.type.namespace", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.ClassTemplate, "entity.name.type.class.templated", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.GenericType, "entity.name.type.class.generic", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.FunctionTemplate, "entity.name.function.templated", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.Namespace, "entity.name.namespace", themeName, textMateRules); this.calculateStyleForToken(TokenKind.Label, "entity.name.label", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.UdlRaw, "entity.name.user-defined-literal", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.UdlNumber, "entity.name.user-defined-literal.number", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.UdlString, "entity.name.user-defined-literal.string", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.UdlRaw, "entity.name.operator.custom-literal", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.UdlNumber, "entity.name.operator.custom-literal.number", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.UdlString, "entity.name.operator.custom-literal.string", themeName, textMateRules); this.calculateStyleForToken(TokenKind.OperatorFunction, "entity.name.function.operator", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.MemberOperator, "keyword.operator.member", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.MemberOperator, "entity.name.function.operator.member", themeName, textMateRules); this.calculateStyleForToken(TokenKind.NewDelete, "keyword.operator.new", themeName, textMateRules); } diff --git a/Extension/src/LanguageServer/protocolFilter.ts b/Extension/src/LanguageServer/protocolFilter.ts index 3b71ad69e..01b63b639 100644 --- a/Extension/src/LanguageServer/protocolFilter.ts +++ b/Extension/src/LanguageServer/protocolFilter.ts @@ -33,11 +33,8 @@ export function createProtocolFilter(me: Client, clients: ClientCollection): Mid } me.onDidOpenTextDocument(document); - me.provideCustomConfiguration(document).then(() => { - sendMessage(document); - }, () => { - sendMessage(document); - }); + me.provideCustomConfiguration(document); + me.notifyWhenReady(() => sendMessage(document)); } }, didChange: (textDocumentChangeEvent, sendMessage) => { diff --git a/Extension/src/common.ts b/Extension/src/common.ts index 6b24452e9..dd3af4cba 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -890,16 +890,14 @@ export class BlockingTask { this.dependency.promise.then(f1, f2); }); } + this.promise.then(() => this.done = true, () => this.done = true); } public get Done(): boolean { return this.done; } - public then(onSucceeded: (value: T) => T2, onRejected?: (err) => any): Thenable { - if (onRejected) { - return this.promise.then(onSucceeded, onRejected); - } - return this.promise.then(onSucceeded); + public getPromise(): Thenable { + return this.promise; } }