From 6a40417d31dd2dc2f33226d01553c7557829808c Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Tue, 15 Mar 2022 23:20:32 -0700 Subject: [PATCH 01/12] Support inlay hints Closes https://github.com/OmniSharp/omnisharp-roslyn/issues/1932. Implements the new inlay hint api for vscode, now that it's stable and in LSP. Tests still need to be written. --- package-lock.json | 16 +++--- package.json | 66 ++++++++++++++++++++++-- src/features/inlayHintProvider.ts | 74 +++++++++++++++++++++++++++ src/observers/OptionChangeObserver.ts | 14 ++++- src/omnisharp/extension.ts | 4 ++ src/omnisharp/options.ts | 37 ++++++++++++++ src/omnisharp/protocol.ts | 21 ++++++++ src/omnisharp/server.ts | 18 +++++++ src/omnisharp/typeConversion.ts | 15 ++++++ src/omnisharp/utils.ts | 8 +++ src/statusBarItemAdapter.ts | 4 +- test/unitTests/Fakes/FakeOptions.ts | 50 +++++++++++++++++- 12 files changed, 312 insertions(+), 15 deletions(-) create mode 100644 src/features/inlayHintProvider.ts diff --git a/package-lock.json b/package-lock.json index 71f43f4fa..707de5b96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "@types/semver": "5.5.0", "@types/tmp": "0.0.33", "@types/unzipper": "^0.9.1", - "@types/vscode": "1.58.0", + "@types/vscode": "1.65.0", "@types/yauzl": "2.9.1", "archiver": "5.3.0", "chai": "4.3.4", @@ -75,7 +75,7 @@ "webpack-cli": "4.6.0" }, "engines": { - "vscode": "^1.61.0" + "vscode": "^1.65.0" } }, "node_modules/@discoveryjs/json-ext": { @@ -322,9 +322,9 @@ } }, "node_modules/@types/vscode": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.58.0.tgz", - "integrity": "sha512-enznxcBi4uYt20LWal09E0+VKEHZlq9PZawTu/mpWCVCFWWbiyR8HNI1ikBP1Ypqv8b3A/0md3DY1jcx+oQ8kQ==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz", + "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", "dev": true }, "node_modules/@types/yauzl": { @@ -9609,9 +9609,9 @@ } }, "@types/vscode": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.58.0.tgz", - "integrity": "sha512-enznxcBi4uYt20LWal09E0+VKEHZlq9PZawTu/mpWCVCFWWbiyR8HNI1ikBP1Ypqv8b3A/0md3DY1jcx+oQ8kQ==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz", + "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", "dev": true }, "@types/yauzl": { diff --git a/package.json b/package.json index d75bc7690..e0ba62304 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "@types/semver": "5.5.0", "@types/tmp": "0.0.33", "@types/unzipper": "^0.9.1", - "@types/vscode": "1.58.0", + "@types/vscode": "1.65.0", "@types/yauzl": "2.9.1", "archiver": "5.3.0", "chai": "4.3.4", @@ -539,7 +539,7 @@ } ], "engines": { - "vscode": "^1.61.0" + "vscode": "^1.65.0" }, "activationEvents": [ "onDebugInitialConfigurations", @@ -852,6 +852,66 @@ "default": true, "description": "Shows the OmniSharp log in the Output pane when OmniSharp reports an error." }, + "csharp.inlayHints.parameters.enabled": { + "type": "boolean", + "default": false, + "description": "Display inline parameter name hints" + }, + "csharp.inlayHints.parameters.forLiteralParameters": { + "type": "boolean", + "default": false, + "description": "Show hints for literals" + }, + "csharp.inlayHints.parameters.forObjectCreationParameters": { + "type": "boolean", + "default": false, + "description": "Show hints for 'new' expressions" + }, + "csharp.inlayHints.parameters.forIndexerParameters": { + "type": "boolean", + "default": false, + "description": "Show hints for indexers" + }, + "csharp.inlayHints.parameters.forOtherParameters": { + "type": "boolean", + "default": false, + "description": "Show hints for everything else" + }, + "csharp.inlayHints.parameters.suppressForParametersThatDifferOnlyBySuffix": { + "type": "boolean", + "default": false, + "description": "Suppress hints when parameter names differ only by suffix" + }, + "csharp.inlayHints.parameters.suppressForParametersThatMatchMethodIntent": { + "type": "boolean", + "default": false, + "description": "Suppress hints when parameter name matches the method's intent" + }, + "csharp.inlayHints.parameters.suppressForParametersThatMatchArgumentName": { + "type": "boolean", + "default": false, + "description": "Suppress hints when argument matches parameter name" + }, + "csharp.inlayHints.types.enabled": { + "type": "boolean", + "default": false, + "description": "Display inline type hints" + }, + "csharp.inlayHints.types.forImplicitVariableTypes": { + "type": "boolean", + "default": false, + "description": "Show hints for variables with inferred types" + }, + "csharp.inlayHints.types.forLambdaParameterTypes": { + "type": "boolean", + "default": false, + "description": "Show hints for lambda parameter types" + }, + "csharp.inlayHints.types.forImplicitObjectCreation": { + "type": "boolean", + "default": false, + "description": "Show hints for implicit object creation" + }, "omnisharp.path": { "type": [ "string", @@ -4011,4 +4071,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/features/inlayHintProvider.ts b/src/features/inlayHintProvider.ts new file mode 100644 index 000000000..3c58e21cb --- /dev/null +++ b/src/features/inlayHintProvider.ts @@ -0,0 +1,74 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as serverUtils from '../omnisharp/utils'; +import * as vscode from 'vscode'; +import AbstractProvider from './abstractProvider'; +import { OmniSharpServer } from '../omnisharp/server'; +import { LanguageMiddlewareFeature } from '../omnisharp/LanguageMiddlewareFeature'; +import CompositeDisposable from '../CompositeDisposable'; +import { InlayHint, InlayHintRequest, InlayHintResolve as InlayHintResolveRequest } from '../omnisharp/protocol'; +import { fromVSCodeRange, toVSCodePosition } from '../omnisharp/typeConversion'; + +export default class CSharpInlayHintProvider extends AbstractProvider implements vscode.InlayHintsProvider { + private readonly _onDidChangeInlayHints = new vscode.EventEmitter(); + public readonly onDidChangeInlayHints = this._onDidChangeInlayHints.event; + + private readonly _hintsMap = new Map(); + + constructor(server: OmniSharpServer, languageMiddlewareFeature: LanguageMiddlewareFeature) { + super(server, languageMiddlewareFeature); + this.addDisposables(new CompositeDisposable( + this._onDidChangeInlayHints, + vscode.workspace.onDidChangeTextDocument(e => { + if (e.document.languageId === 'csharp') { + this._onDidChangeInlayHints.fire(); + } + }))); + } + + async provideInlayHints(document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { + const request: InlayHintRequest = { + Location: { + FileName: document.fileName, + Range: fromVSCodeRange(range) + } + }; + + try { + const hints = await serverUtils.getInlayHints(this._server, request, token); + + return hints.InlayHints.map((inlayHint): vscode.InlayHint => { + const mappedHint = this.toVscodeHint(inlayHint); + this._hintsMap.set(mappedHint, inlayHint); + return mappedHint; + }); + } catch (error) { + return Promise.reject(`Problem invoking 'GetInlayHints' on OmniSharpServer: ${error}`); + } + } + + async resolveInlayHint?(hint: vscode.InlayHint, token: vscode.CancellationToken): Promise { + if (!this._hintsMap.has(hint)) { + return Promise.reject(`Outdated inlay hint was requested to be resolved, aborting.`); + } + + const request: InlayHintResolveRequest = { Hint: this._hintsMap.get(hint) }; + + try { + const result = await serverUtils.resolveInlayHints(this._server, request, token); + return this.toVscodeHint(result); + } catch (error) { + return Promise.reject(`Problem invoking 'ResolveInlayHints' on OmniSharpServer: ${error}`); + } + } + + private toVscodeHint(inlayHint: InlayHint): vscode.InlayHint { + return { + label: inlayHint.Label, + position: toVSCodePosition(inlayHint.Position), + tooltip: new vscode.MarkdownString(inlayHint.Tooltip ?? "") + }; + } +} diff --git a/src/observers/OptionChangeObserver.ts b/src/observers/OptionChangeObserver.ts index 52b88a7aa..279786b84 100644 --- a/src/observers/OptionChangeObserver.ts +++ b/src/observers/OptionChangeObserver.ts @@ -25,7 +25,19 @@ const omniSharpOptions: ReadonlyArray = [ "enableAsyncCompletion", "useModernNet", "analyzeOpenDocumentsOnly", - "enableRoslynAnalyzers" + "enableRoslynAnalyzers", + "enableForParameters", + "forLiteralParameters", + "forObjectCreationParameters", + "forIndexerParameters", + "forOtherParameters", + "suppressForParametersThatDifferOnlyBySuffix", + "suppressForParametersThatMatchMethodIntent", + "suppressForParametersThatMatchArgumentName", + "enableForTypes", + "forImplicitVariableTypes", + "forLambdaParameterTypes", + "forImplicitObjectCreation", ]; function OmniSharpOptionChangeObservable(optionObservable: Observable): Observable { diff --git a/src/omnisharp/extension.ts b/src/omnisharp/extension.ts index d7add1c56..01171fa3c 100644 --- a/src/omnisharp/extension.ts +++ b/src/omnisharp/extension.ts @@ -44,6 +44,7 @@ import SemanticTokensProvider from '../features/semanticTokensProvider'; import SourceGeneratedDocumentProvider from '../features/sourceGeneratedDocumentProvider'; import { getDecompilationAuthorization } from './decompilationPrompt'; import { OmniSharpDotnetResolver } from './OmniSharpDotnetResolver'; +import CSharpInlayHintProvider from '../features/inlayHintProvider'; import fileOpenClose from '../features/fileOpenCloseProvider'; export interface ActivationResult { @@ -119,6 +120,9 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an const semanticTokensProvider = new SemanticTokensProvider(server, optionProvider, languageMiddlewareFeature); localDisposables.add(vscode.languages.registerDocumentSemanticTokensProvider(documentSelector, semanticTokensProvider, semanticTokensProvider.getLegend())); localDisposables.add(vscode.languages.registerDocumentRangeSemanticTokensProvider(documentSelector, semanticTokensProvider, semanticTokensProvider.getLegend())); + + const inlayHintsProvider = new CSharpInlayHintProvider(server, languageMiddlewareFeature); + localDisposables.add(vscode.languages.registerInlayHintsProvider(documentSelector, inlayHintsProvider)); })); disposables.add(server.onServerStop(() => { diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index f262027bb..669ca59fc 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -36,6 +36,18 @@ export class Options { public enableAsyncCompletion: boolean, public analyzeOpenDocumentsOnly: boolean, public useSemanticHighlighting: boolean, + public enableForParameters: boolean, + public forLiteralParameters: boolean, + public forObjectCreationParameters: boolean, + public forIndexerParameters: boolean, + public forOtherParameters: boolean, + public suppressForParametersThatDifferOnlyBySuffix: boolean, + public suppressForParametersThatMatchMethodIntent: boolean, + public suppressForParametersThatMatchArgumentName: boolean, + public enableForTypes: boolean, + public forImplicitVariableTypes: boolean, + public forLambdaParameterTypes: boolean, + public forImplicitObjectCreation: boolean, public razorPluginPath?: string, public defaultLaunchSolution?: string, public monoPath?: string, @@ -94,6 +106,19 @@ export class Options { const useSemanticHighlighting = csharpConfig.get('semanticHighlighting.enabled', false); + const enableForParameters = csharpConfig.get('inlayHints.parameters.enabled', false); + const forLiteralParameters = csharpConfig.get('inlayHints.parameters.forLiteralParameters', false); + const forObjectCreationParameters = csharpConfig.get('inlayHints.parameters.forObjectCreationParameters', false); + const forIndexerParameters = csharpConfig.get('inlayHints.parameters.forIndexerParameters', false); + const forOtherParameters = csharpConfig.get('inlayHints.parameters.forOtherParameters', false); + const suppressForParametersThatDifferOnlyBySuffix = csharpConfig.get('inlayHints.parameters.suppressForParametersThatDifferOnlyBySuffix', false); + const suppressForParametersThatMatchMethodIntent = csharpConfig.get('inlayHints.parameters.suppressForParametersThatMatchMethodIntent', false); + const suppressForParametersThatMatchArgumentName = csharpConfig.get('inlayHints.parameters.suppressForParametersThatMatchArgumentName', false); + const enableForTypes = csharpConfig.get('inlayHints.types.enabled', false); + const forImplicitVariableTypes = csharpConfig.get('inlayHints.types.forImplicitVariableTypes', false); + const forLambdaParameterTypes = csharpConfig.get('inlayHints.types.forLambdaParameterTypes', false); + const forImplicitObjectCreation = csharpConfig.get('inlayHints.types.forImplicitObjectCreation', false); + const disableCodeActions = csharpConfig.get('disableCodeActions', false); const disableMSBuildDiagnosticWarning = omnisharpConfig.get('disableMSBuildDiagnosticWarning', false); @@ -145,6 +170,18 @@ export class Options { enableAsyncCompletion, analyzeOpenDocumentsOnly, useSemanticHighlighting, + enableForParameters, + forLiteralParameters, + forObjectCreationParameters, + forIndexerParameters, + forOtherParameters, + suppressForParametersThatDifferOnlyBySuffix, + suppressForParametersThatMatchMethodIntent, + suppressForParametersThatMatchArgumentName, + enableForTypes, + forImplicitVariableTypes, + forLambdaParameterTypes, + forImplicitObjectCreation, razorPluginPath, defaultLaunchSolution, monoPath, diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index f028cf427..977a8991c 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -38,6 +38,8 @@ export module Requests { export const SourceGeneratedFile = '/sourcegeneratedfile'; export const UpdateSourceGeneratedFile = '/updatesourcegeneratedfile'; export const SourceGeneratedFileClosed = '/sourcegeneratedfileclosed'; + export const InlayHint = '/inlayHint'; + export const InlayHintResolve = '/inlayHint/resolve'; export const FileOpen = '/open'; export const FileClose = '/close'; } @@ -581,6 +583,25 @@ export enum UpdateType { export interface SourceGeneratedFileClosedRequest extends SourceGeneratedFileInfo { } +export interface InlayHintRequest { + Location: V2.Location; +} + +export interface InlayHint { + Position: V2.Point; + Label: string; + Tooltip?: string; + Data: any; +} + +export interface InlayHintResponse { + InlayHints: InlayHint[]; +} + +export interface InlayHintResolve { + Hint: InlayHint; +} + export interface Definition { Location: V2.Location; MetadataSource?: MetadataSource; diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index 19ad83141..04abf8e77 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -391,6 +391,24 @@ export class OmniSharpServer { args.push('RoslynExtensionsOptions:EnableAsyncCompletion=true'); } + if (options.enableForParameters === true) { + args.push(`RoslynExtensionsOptions:InlayHintsOptions:EnableForParameters=${options.enableForParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForLiteralParameters=${options.forLiteralParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForIndexerParameters=${options.forIndexerParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForObjectCreationParameters=${options.forObjectCreationParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForOtherParameters=${options.forOtherParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatDifferOnlyBySuffix=${options.suppressForParametersThatDifferOnlyBySuffix.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatMatchMethodIntent=${options.suppressForParametersThatMatchMethodIntent.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatMatchArgumentName=${options.suppressForParametersThatMatchArgumentName.toString()}`); + } + + if (options.enableForTypes === true) { + args.push(`RoslynExtensionsOptions:InlayHintsOptions:EnableForTypes=${options.enableForTypes.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForImplicitVariableTypes=${options.forImplicitVariableTypes.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForLambdaParameterTypes=${options.forLambdaParameterTypes.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForImplicitObjectCreation=${options.forImplicitObjectCreation.toString()}`); + } + if (options.analyzeOpenDocumentsOnly === true) { args.push('RoslynExtensionsOptions:AnalyzeOpenDocumentsOnly=true'); } diff --git a/src/omnisharp/typeConversion.ts b/src/omnisharp/typeConversion.ts index 6771d7544..f6b183c94 100644 --- a/src/omnisharp/typeConversion.ts +++ b/src/omnisharp/typeConversion.ts @@ -47,6 +47,21 @@ export function toVSCodeRange(StartLine: number, StartColumn: number, EndLine: n return new vscode.Range(StartLine, StartColumn, EndLine, EndColumn); } +export function fromVSCodeRange(range: vscode.Range): protocol.V2.Range { + return { + Start: fromVSCodePosition(range.start), + End: fromVSCodePosition(range.end) + }; +} + +export function fromVSCodePosition(position: vscode.Position): protocol.V2.Point { + return { Line: position.line, Column: position.character }; +} + +export function toVSCodePosition(point: protocol.V2.Point): vscode.Position { + return new vscode.Position(point.Line, point.Column); +} + export function createRequest(document: vscode.TextDocument, where: vscode.Position | vscode.Range, includeBuffer: boolean = false): T { let Line: number, Column: number; diff --git a/src/omnisharp/utils.ts b/src/omnisharp/utils.ts index 0bd5d5589..cac8b3dc8 100644 --- a/src/omnisharp/utils.ts +++ b/src/omnisharp/utils.ts @@ -209,6 +209,14 @@ export async function isNetCoreProject(project: protocol.MSBuildProject) { return project.TargetFrameworks.find(tf => tf.ShortName.startsWith('netcoreapp') || tf.ShortName.startsWith('netstandard')) !== undefined; } +export async function getInlayHints(server: OmniSharpServer, request: protocol.InlayHintRequest, context: vscode.CancellationToken) { + return server.makeRequest(protocol.Requests.InlayHint, request, context); +} + +export async function resolveInlayHints(server: OmniSharpServer, request: protocol.InlayHintResolve, context: vscode.CancellationToken) { + return server.makeRequest(protocol.Requests.InlayHintResolve, request, context); +} + function isBlazorWebAssemblyHosted(project: protocol.MSBuildProject, isProjectBlazorWebAssemblyProject: boolean): boolean { if (!isProjectBlazorWebAssemblyProject) { return false; diff --git a/src/statusBarItemAdapter.ts b/src/statusBarItemAdapter.ts index 6aea6c908..1bf6ddbcf 100644 --- a/src/statusBarItemAdapter.ts +++ b/src/statusBarItemAdapter.ts @@ -25,7 +25,7 @@ export class StatusBarItemAdapter implements vscodeAdapter.StatusBarItem { } get tooltip(): string { - return this.statusBarItem.tooltip; + return this.statusBarItem.tooltip; } set tooltip(value: string) { @@ -70,4 +70,4 @@ export class StatusBarItemAdapter implements vscodeAdapter.StatusBarItem { constructor(private statusBarItem: vscode.StatusBarItem) { } -} \ No newline at end of file +} diff --git a/test/unitTests/Fakes/FakeOptions.ts b/test/unitTests/Fakes/FakeOptions.ts index 7164c6a87..92b28d02c 100644 --- a/test/unitTests/Fakes/FakeOptions.ts +++ b/test/unitTests/Fakes/FakeOptions.ts @@ -6,5 +6,53 @@ import { Options } from "../../../src/omnisharp/options"; export function getEmptyOptions(): Options { - return new Options("", false, "", false, "", false, 0, 0, false, false, false, false, false, [], false, false, false, 0, 0, false, false, false, false, false, false, false, false, false, undefined, "", "", ""); + return new Options( + /* path */"", + /* useModernNet */false, + /* useGlobalMono */"", + /* waitForDebugger */false, + /* loggingLevel */"", + /* autoStart */false, + /* projectLoadTimeout */0, + /* maxProjectResults */0, + /* useEditorFormattingSettings */false, + /* useFormatting */false, + /* organizeImportsOnFormat */false, + /* showReferencesCodeLens */false, + /* showTestsCodeLens */false, + /* filteredSymbolsCodeLens */undefined, + /* disableCodeActions */false, + /* disableMSBuildDiagnosticWarning */false, + /* showOmnisharpLogOnError */false, + /* minFindSymbolsFilterLength */0, + /* maxFindSymbolsItems */0, + /* razorDisabled */false, + /* razorDevMode */false, + /* enableMsBuildLoadProjectsOnDemand */false, + /* enableRoslynAnalyzers */false, + /* enableEditorConfigSupport */false, + /* enableDecompilationSupport */false, + /* enableImportCompletion */false, + /* enableAsyncCompletion */false, + /* analyzeOpenDocumentsOnly */false, + /* useSemanticHighlighting */false, + /* enableForParameters */false, + /* forLiteralParameters */false, + /* forObjectCreationParameters */false, + /* forIndexerParameters */false, + /* forOtherParameters */false, + /* suppressForParametersThatDifferOnlyBySuffix */false, + /* suppressForParametersThatMatchMethodIntent */false, + /* suppressForParametersThatMatchArgumentName */false, + /* enableForTypes */false, + /* forImplicitVariableTypes */false, + /* forLambdaParameterTypes */false, + /* forImplicitObjectCreation */false, + /* razorPluginPath */"", + /* defaultLaunchSolution */"", + /* monoPath */"", + /* dotnetPath */"", + /* excludePaths */null, + /* maxProjectFileCountForDiagnosticAnalysis */null, + /* testRunSettings */""); } From e31061a9967a08aac2d1e28ac90b5c780f812bd8 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 19:52:14 -0700 Subject: [PATCH 02/12] Add inlay hint integration test --- .../inlayHints.integration.test.ts | 71 +++++++++++++++++++ .../testAssets/singleCsproj/inlayHints.cs | 29 ++++++++ .../slnFilterWithCsproj/src/app/inlayHints.cs | 29 ++++++++ .../slnWithCsproj/src/app/inlayHints.cs | 29 ++++++++ 4 files changed, 158 insertions(+) create mode 100644 test/integrationTests/inlayHints.integration.test.ts create mode 100644 test/integrationTests/testAssets/singleCsproj/inlayHints.cs create mode 100644 test/integrationTests/testAssets/slnFilterWithCsproj/src/app/inlayHints.cs create mode 100644 test/integrationTests/testAssets/slnWithCsproj/src/app/inlayHints.cs diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts new file mode 100644 index 000000000..5aa34c0b8 --- /dev/null +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -0,0 +1,71 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; + +import { should, assert } from 'chai'; +import { activateCSharpExtension, isRazorWorkspace, isSlnWithGenerator } from './integrationHelpers'; +import testAssetWorkspace from './testAssets/testAssetWorkspace'; +import * as path from 'path'; + +const chai = require('chai'); +chai.use(require('chai-arrays')); +chai.use(require('chai-fs')); + +suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { + let fileUri: vscode.Uri; + + suiteSetup(async function () { + should(); + + if (isRazorWorkspace(vscode.workspace) || isSlnWithGenerator(vscode.workspace)) { + this.skip(); + } + + const csharpConfig = vscode.workspace.getConfiguration('csharp'); + csharpConfig.update('inlayhints.parameters.enabled', true); + csharpConfig.update('inlayhints.parameters.forLiteralParameters', true); + csharpConfig.update('inlayhints.parameters.forObjectCreationParameters', true); + csharpConfig.update('inlayhints.parameters.forIndexerParameters', true); + csharpConfig.update('inlayhints.parameters.forOtherParameters', true); + csharpConfig.update('inlayhints.parameters.suppressForParametersThatDifferOnlyBySuffix', true); + csharpConfig.update('inlayhints.parameters.suppressForParametersThatMatchMethodIntent', true); + csharpConfig.update('inlayhints.parameters.suppressForParametersThatMatchArgumentName', true); + csharpConfig.update('inlayhints.types.enabled', true); + csharpConfig.update('inlayhints.types.forImplicitVariableTypes', true); + csharpConfig.update('inlayhints.types.forLambdaParameterTypes', true); + csharpConfig.update('inlayhints.types.forImplicitObjectCreation', true); + + const activation = await activateCSharpExtension(); + await testAssetWorkspace.restoreAndWait(activation); + + const fileName = 'inlayHints.cs'; + const projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; + const filePath = path.join(projectDirectory, fileName); + fileUri = vscode.Uri.file(filePath); + }); + + suiteTeardown(async () => { + await testAssetWorkspace.cleanupWorkspace(); + }); + + test.only("Hints retrieved for region", async () => { + const range = new vscode.Range(new vscode.Position(4, 8), new vscode.Position(15, 85)); + const hints : vscode.InlayHint[] = await vscode.commands.executeCommand('vscode.executeInlayHintProvider', fileUri, range); + assert.lengthOf(hints, 6); + assertValues(hints[0], 'InlayHints ', 6, 12); + assertValues(hints[1], ' InlayHints', 7, 27); + assertValues(hints[2], 'string ', 8, 28); + assertValues(hints[3], 'i: ', 9, 17); + assertValues(hints[4], 'param1: ', 10, 15); + assertValues(hints[5], 'param1: ', 11, 27); + + function assertValues(hint: vscode.InlayHint, expectedLabel: string, expectedLine: number, expectedCharacter: number) { + assert.equal(hint.label, expectedLabel); + assert.equal(hint.position.line, expectedLine); + assert.equal(hint.position.character, expectedCharacter); + } + }); +}); diff --git a/test/integrationTests/testAssets/singleCsproj/inlayHints.cs b/test/integrationTests/testAssets/singleCsproj/inlayHints.cs new file mode 100644 index 000000000..c34ad62dc --- /dev/null +++ b/test/integrationTests/testAssets/singleCsproj/inlayHints.cs @@ -0,0 +1,29 @@ +using System; + +class InlayHints +{ + public void M() + { + var l1 = new InlayHints(); + InlayHints l2 = new(); + Action a = (s) => { }; + _ = this[1]; + _ = M1(1); + _ = new InlayHints(1); + _ = M2(1, 2); // No hint here, suppressForParametersThatDifferOnlyBySuffix + + int param1 = 1; + _ = M1(param1); // No hint here, suppressForParametersThatMatchArgumentName + + _ = EnableM(true); // No hint here, suppressForParametersThatMatchMethodIntent + } + + public void M1(int param1) { } + public void M2(int param1, int param2) { } + public void EnableM(bool enable) { } + + public int this[int i] { get { return 0; } set { } } + + public InlayHints() {} + public InlayHints(int param1) {} +} diff --git a/test/integrationTests/testAssets/slnFilterWithCsproj/src/app/inlayHints.cs b/test/integrationTests/testAssets/slnFilterWithCsproj/src/app/inlayHints.cs new file mode 100644 index 000000000..c34ad62dc --- /dev/null +++ b/test/integrationTests/testAssets/slnFilterWithCsproj/src/app/inlayHints.cs @@ -0,0 +1,29 @@ +using System; + +class InlayHints +{ + public void M() + { + var l1 = new InlayHints(); + InlayHints l2 = new(); + Action a = (s) => { }; + _ = this[1]; + _ = M1(1); + _ = new InlayHints(1); + _ = M2(1, 2); // No hint here, suppressForParametersThatDifferOnlyBySuffix + + int param1 = 1; + _ = M1(param1); // No hint here, suppressForParametersThatMatchArgumentName + + _ = EnableM(true); // No hint here, suppressForParametersThatMatchMethodIntent + } + + public void M1(int param1) { } + public void M2(int param1, int param2) { } + public void EnableM(bool enable) { } + + public int this[int i] { get { return 0; } set { } } + + public InlayHints() {} + public InlayHints(int param1) {} +} diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/inlayHints.cs b/test/integrationTests/testAssets/slnWithCsproj/src/app/inlayHints.cs new file mode 100644 index 000000000..c34ad62dc --- /dev/null +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/inlayHints.cs @@ -0,0 +1,29 @@ +using System; + +class InlayHints +{ + public void M() + { + var l1 = new InlayHints(); + InlayHints l2 = new(); + Action a = (s) => { }; + _ = this[1]; + _ = M1(1); + _ = new InlayHints(1); + _ = M2(1, 2); // No hint here, suppressForParametersThatDifferOnlyBySuffix + + int param1 = 1; + _ = M1(param1); // No hint here, suppressForParametersThatMatchArgumentName + + _ = EnableM(true); // No hint here, suppressForParametersThatMatchMethodIntent + } + + public void M1(int param1) { } + public void M2(int param1, int param2) { } + public void EnableM(bool enable) { } + + public int this[int i] { get { return 0; } set { } } + + public InlayHints() {} + public InlayHints(int param1) {} +} From fde7c6fdca43c9937fd0fa639872acbcab90e660 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 20:06:03 -0700 Subject: [PATCH 03/12] PR feedback. --- src/features/inlayHintProvider.ts | 5 ++ src/observers/OptionChangeObserver.ts | 24 +++---- src/omnisharp/options.ts | 72 +++++++++---------- src/omnisharp/server.ts | 32 ++++----- .../inlayHints.integration.test.ts | 2 +- test/unitTests/Fakes/FakeOptions.ts | 24 +++---- 6 files changed, 82 insertions(+), 77 deletions(-) diff --git a/src/features/inlayHintProvider.ts b/src/features/inlayHintProvider.ts index 3c58e21cb..b6f0f8ae3 100644 --- a/src/features/inlayHintProvider.ts +++ b/src/features/inlayHintProvider.ts @@ -10,6 +10,7 @@ import { LanguageMiddlewareFeature } from '../omnisharp/LanguageMiddlewareFeatur import CompositeDisposable from '../CompositeDisposable'; import { InlayHint, InlayHintRequest, InlayHintResolve as InlayHintResolveRequest } from '../omnisharp/protocol'; import { fromVSCodeRange, toVSCodePosition } from '../omnisharp/typeConversion'; +import { isVirtualCSharpDocument } from './virtualDocumentTracker'; export default class CSharpInlayHintProvider extends AbstractProvider implements vscode.InlayHintsProvider { private readonly _onDidChangeInlayHints = new vscode.EventEmitter(); @@ -29,6 +30,10 @@ export default class CSharpInlayHintProvider extends AbstractProvider implements } async provideInlayHints(document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { + if (isVirtualCSharpDocument(document)) { + return []; + } + const request: InlayHintRequest = { Location: { FileName: document.fileName, diff --git a/src/observers/OptionChangeObserver.ts b/src/observers/OptionChangeObserver.ts index 279786b84..3553131c1 100644 --- a/src/observers/OptionChangeObserver.ts +++ b/src/observers/OptionChangeObserver.ts @@ -26,18 +26,18 @@ const omniSharpOptions: ReadonlyArray = [ "useModernNet", "analyzeOpenDocumentsOnly", "enableRoslynAnalyzers", - "enableForParameters", - "forLiteralParameters", - "forObjectCreationParameters", - "forIndexerParameters", - "forOtherParameters", - "suppressForParametersThatDifferOnlyBySuffix", - "suppressForParametersThatMatchMethodIntent", - "suppressForParametersThatMatchArgumentName", - "enableForTypes", - "forImplicitVariableTypes", - "forLambdaParameterTypes", - "forImplicitObjectCreation", + "inlayHintsEnableForParameters", + "inlayHintsForLiteralParameters", + "inlayHintsForObjectCreationParameters", + "inlayHintsForIndexerParameters", + "inlayHintsForOtherParameters", + "inlayHintsSuppressForParametersThatDifferOnlyBySuffix", + "inlayHintsSuppressForParametersThatMatchMethodIntent", + "inlayHintsSuppressForParametersThatMatchArgumentName", + "inlayHintsEnableForTypes", + "inlayHintsForImplicitVariableTypes", + "inlayHintsForLambdaParameterTypes", + "inlayHintsForImplicitObjectCreation", ]; function OmniSharpOptionChangeObservable(optionObservable: Observable): Observable { diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index 669ca59fc..1025f5b0a 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -36,18 +36,18 @@ export class Options { public enableAsyncCompletion: boolean, public analyzeOpenDocumentsOnly: boolean, public useSemanticHighlighting: boolean, - public enableForParameters: boolean, - public forLiteralParameters: boolean, - public forObjectCreationParameters: boolean, - public forIndexerParameters: boolean, - public forOtherParameters: boolean, - public suppressForParametersThatDifferOnlyBySuffix: boolean, - public suppressForParametersThatMatchMethodIntent: boolean, - public suppressForParametersThatMatchArgumentName: boolean, - public enableForTypes: boolean, - public forImplicitVariableTypes: boolean, - public forLambdaParameterTypes: boolean, - public forImplicitObjectCreation: boolean, + public inlayHintsEnableForParameters: boolean, + public inlayHintsForLiteralParameters: boolean, + public inlayHintsForObjectCreationParameters: boolean, + public inlayHintsForIndexerParameters: boolean, + public inlayHintsForOtherParameters: boolean, + public inlayHintsSuppressForParametersThatDifferOnlyBySuffix: boolean, + public inlayHintsSuppressForParametersThatMatchMethodIntent: boolean, + public inlayHintsSuppressForParametersThatMatchArgumentName: boolean, + public inlayHintsEnableForTypes: boolean, + public inlayHintsForImplicitVariableTypes: boolean, + public inlayHintsForLambdaParameterTypes: boolean, + public inlayHintsForImplicitObjectCreation: boolean, public razorPluginPath?: string, public defaultLaunchSolution?: string, public monoPath?: string, @@ -106,18 +106,18 @@ export class Options { const useSemanticHighlighting = csharpConfig.get('semanticHighlighting.enabled', false); - const enableForParameters = csharpConfig.get('inlayHints.parameters.enabled', false); - const forLiteralParameters = csharpConfig.get('inlayHints.parameters.forLiteralParameters', false); - const forObjectCreationParameters = csharpConfig.get('inlayHints.parameters.forObjectCreationParameters', false); - const forIndexerParameters = csharpConfig.get('inlayHints.parameters.forIndexerParameters', false); - const forOtherParameters = csharpConfig.get('inlayHints.parameters.forOtherParameters', false); - const suppressForParametersThatDifferOnlyBySuffix = csharpConfig.get('inlayHints.parameters.suppressForParametersThatDifferOnlyBySuffix', false); - const suppressForParametersThatMatchMethodIntent = csharpConfig.get('inlayHints.parameters.suppressForParametersThatMatchMethodIntent', false); - const suppressForParametersThatMatchArgumentName = csharpConfig.get('inlayHints.parameters.suppressForParametersThatMatchArgumentName', false); - const enableForTypes = csharpConfig.get('inlayHints.types.enabled', false); - const forImplicitVariableTypes = csharpConfig.get('inlayHints.types.forImplicitVariableTypes', false); - const forLambdaParameterTypes = csharpConfig.get('inlayHints.types.forLambdaParameterTypes', false); - const forImplicitObjectCreation = csharpConfig.get('inlayHints.types.forImplicitObjectCreation', false); + const inlayHintsEnableForParameters = csharpConfig.get('inlayHints.parameters.enabled', false); + const inlayHintsForLiteralParameters = csharpConfig.get('inlayHints.parameters.forLiteralParameters', false); + const inlayHintsForObjectCreationParameters = csharpConfig.get('inlayHints.parameters.forObjectCreationParameters', false); + const inlayHintsForIndexerParameters = csharpConfig.get('inlayHints.parameters.forIndexerParameters', false); + const inlayHintsForOtherParameters = csharpConfig.get('inlayHints.parameters.forOtherParameters', false); + const inlayHintsSuppressForParametersThatDifferOnlyBySuffix = csharpConfig.get('inlayHints.parameters.suppressForParametersThatDifferOnlyBySuffix', false); + const inlayHintsSuppressForParametersThatMatchMethodIntent = csharpConfig.get('inlayHints.parameters.suppressForParametersThatMatchMethodIntent', false); + const inlayHintsSuppressForParametersThatMatchArgumentName = csharpConfig.get('inlayHints.parameters.suppressForParametersThatMatchArgumentName', false); + const inlayHintsEnableForTypes = csharpConfig.get('inlayHints.types.enabled', false); + const inlayHintsForImplicitVariableTypes = csharpConfig.get('inlayHints.types.forImplicitVariableTypes', false); + const inlayHintsForLambdaParameterTypes = csharpConfig.get('inlayHints.types.forLambdaParameterTypes', false); + const inlayHintsForImplicitObjectCreation = csharpConfig.get('inlayHints.types.forImplicitObjectCreation', false); const disableCodeActions = csharpConfig.get('disableCodeActions', false); @@ -170,18 +170,18 @@ export class Options { enableAsyncCompletion, analyzeOpenDocumentsOnly, useSemanticHighlighting, - enableForParameters, - forLiteralParameters, - forObjectCreationParameters, - forIndexerParameters, - forOtherParameters, - suppressForParametersThatDifferOnlyBySuffix, - suppressForParametersThatMatchMethodIntent, - suppressForParametersThatMatchArgumentName, - enableForTypes, - forImplicitVariableTypes, - forLambdaParameterTypes, - forImplicitObjectCreation, + inlayHintsEnableForParameters, + inlayHintsForLiteralParameters, + inlayHintsForObjectCreationParameters, + inlayHintsForIndexerParameters, + inlayHintsForOtherParameters, + inlayHintsSuppressForParametersThatDifferOnlyBySuffix, + inlayHintsSuppressForParametersThatMatchMethodIntent, + inlayHintsSuppressForParametersThatMatchArgumentName, + inlayHintsEnableForTypes, + inlayHintsForImplicitVariableTypes, + inlayHintsForLambdaParameterTypes, + inlayHintsForImplicitObjectCreation, razorPluginPath, defaultLaunchSolution, monoPath, diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index 04abf8e77..b8927b497 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -391,22 +391,22 @@ export class OmniSharpServer { args.push('RoslynExtensionsOptions:EnableAsyncCompletion=true'); } - if (options.enableForParameters === true) { - args.push(`RoslynExtensionsOptions:InlayHintsOptions:EnableForParameters=${options.enableForParameters.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForLiteralParameters=${options.forLiteralParameters.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForIndexerParameters=${options.forIndexerParameters.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForObjectCreationParameters=${options.forObjectCreationParameters.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForOtherParameters=${options.forOtherParameters.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatDifferOnlyBySuffix=${options.suppressForParametersThatDifferOnlyBySuffix.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatMatchMethodIntent=${options.suppressForParametersThatMatchMethodIntent.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatMatchArgumentName=${options.suppressForParametersThatMatchArgumentName.toString()}`); - } - - if (options.enableForTypes === true) { - args.push(`RoslynExtensionsOptions:InlayHintsOptions:EnableForTypes=${options.enableForTypes.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForImplicitVariableTypes=${options.forImplicitVariableTypes.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForLambdaParameterTypes=${options.forLambdaParameterTypes.toString()}`); - args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForImplicitObjectCreation=${options.forImplicitObjectCreation.toString()}`); + if (options.inlayHintsEnableForParameters === true) { + args.push(`RoslynExtensionsOptions:InlayHintsOptions:EnableForParameters=${options.inlayHintsEnableForParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForLiteralParameters=${options.inlayHintsForLiteralParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForIndexerParameters=${options.inlayHintsForIndexerParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForObjectCreationParameters=${options.inlayHintsForObjectCreationParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForOtherParameters=${options.inlayHintsForOtherParameters.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatDifferOnlyBySuffix=${options.inlayHintsSuppressForParametersThatDifferOnlyBySuffix.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatMatchMethodIntent=${options.inlayHintsSuppressForParametersThatMatchMethodIntent.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:SuppressForParametersThatMatchArgumentName=${options.inlayHintsSuppressForParametersThatMatchArgumentName.toString()}`); + } + + if (options.inlayHintsEnableForTypes === true) { + args.push(`RoslynExtensionsOptions:InlayHintsOptions:EnableForTypes=${options.inlayHintsEnableForTypes.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForImplicitVariableTypes=${options.inlayHintsForImplicitVariableTypes.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForLambdaParameterTypes=${options.inlayHintsForLambdaParameterTypes.toString()}`); + args.push(`RoslynExtensionsOptions:InlayHintsOptions:ForImplicitObjectCreation=${options.inlayHintsForImplicitObjectCreation.toString()}`); } if (options.analyzeOpenDocumentsOnly === true) { diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index 5aa34c0b8..971d9ef09 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -27,7 +27,7 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { const csharpConfig = vscode.workspace.getConfiguration('csharp'); csharpConfig.update('inlayhints.parameters.enabled', true); csharpConfig.update('inlayhints.parameters.forLiteralParameters', true); - csharpConfig.update('inlayhints.parameters.forObjectCreationParameters', true); + csharpConfig.update('inlayhints.parameters.inlayHintsForObjectCreationParameters', true); csharpConfig.update('inlayhints.parameters.forIndexerParameters', true); csharpConfig.update('inlayhints.parameters.forOtherParameters', true); csharpConfig.update('inlayhints.parameters.suppressForParametersThatDifferOnlyBySuffix', true); diff --git a/test/unitTests/Fakes/FakeOptions.ts b/test/unitTests/Fakes/FakeOptions.ts index 92b28d02c..f4b940a90 100644 --- a/test/unitTests/Fakes/FakeOptions.ts +++ b/test/unitTests/Fakes/FakeOptions.ts @@ -36,18 +36,18 @@ export function getEmptyOptions(): Options { /* enableAsyncCompletion */false, /* analyzeOpenDocumentsOnly */false, /* useSemanticHighlighting */false, - /* enableForParameters */false, - /* forLiteralParameters */false, - /* forObjectCreationParameters */false, - /* forIndexerParameters */false, - /* forOtherParameters */false, - /* suppressForParametersThatDifferOnlyBySuffix */false, - /* suppressForParametersThatMatchMethodIntent */false, - /* suppressForParametersThatMatchArgumentName */false, - /* enableForTypes */false, - /* forImplicitVariableTypes */false, - /* forLambdaParameterTypes */false, - /* forImplicitObjectCreation */false, + /* inlayHintsEnableForParameters */false, + /* inlayHintsForLiteralParameters */false, + /* inlayHintsForObjectCreationParameters */false, + /* inlayHintsForIndexerParameters */false, + /* inlayHintsForOtherParameters */false, + /* inlayHintsSuppressForParametersThatDifferOnlyBySuffix */false, + /* inlayHintsSuppressForParametersThatMatchMethodIntent */false, + /* inlayHintsSuppressForParametersThatMatchArgumentName */false, + /* inlayHintsEnableForTypes */false, + /* inlayHintsForImplicitVariableTypes */false, + /* inlayHintsForLambdaParameterTypes */false, + /* inlayHintsForImplicitObjectCreation */false, /* razorPluginPath */"", /* defaultLaunchSolution */"", /* monoPath */"", From fca58278f211ad486d58bf99f9b7fee9e7c7a65e Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 20:12:53 -0700 Subject: [PATCH 04/12] Correct configs --- .../inlayHints.integration.test.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index 971d9ef09..c61c49be6 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -25,18 +25,18 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { } const csharpConfig = vscode.workspace.getConfiguration('csharp'); - csharpConfig.update('inlayhints.parameters.enabled', true); - csharpConfig.update('inlayhints.parameters.forLiteralParameters', true); - csharpConfig.update('inlayhints.parameters.inlayHintsForObjectCreationParameters', true); - csharpConfig.update('inlayhints.parameters.forIndexerParameters', true); - csharpConfig.update('inlayhints.parameters.forOtherParameters', true); - csharpConfig.update('inlayhints.parameters.suppressForParametersThatDifferOnlyBySuffix', true); - csharpConfig.update('inlayhints.parameters.suppressForParametersThatMatchMethodIntent', true); - csharpConfig.update('inlayhints.parameters.suppressForParametersThatMatchArgumentName', true); - csharpConfig.update('inlayhints.types.enabled', true); - csharpConfig.update('inlayhints.types.forImplicitVariableTypes', true); - csharpConfig.update('inlayhints.types.forLambdaParameterTypes', true); - csharpConfig.update('inlayhints.types.forImplicitObjectCreation', true); + csharpConfig.update('inlayHints.parameters.enabled', true); + csharpConfig.update('inlayHints.parameters.forLiteralParameters', true); + csharpConfig.update('inlayHints.parameters.forObjectCreationParameters', true); + csharpConfig.update('inlayHints.parameters.forIndexerParameters', true); + csharpConfig.update('inlayHints.parameters.forOtherParameters', true); + csharpConfig.update('inlayHints.parameters.suppressForParametersThatDifferOnlyBySuffix', true); + csharpConfig.update('inlayHints.parameters.suppressForParametersThatMatchMethodIntent', true); + csharpConfig.update('inlayHints.parameters.suppressForParametersThatMatchArgumentName', true); + csharpConfig.update('inlayHints.types.enabled', true); + csharpConfig.update('inlayHints.types.forImplicitVariableTypes', true); + csharpConfig.update('inlayHints.types.forLambdaParameterTypes', true); + csharpConfig.update('inlayHints.types.forImplicitObjectCreation', true); const activation = await activateCSharpExtension(); await testAssetWorkspace.restoreAndWait(activation); From d6bc4eafcb08621a4c51de769325a765273bbdfe Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 20:18:16 -0700 Subject: [PATCH 05/12] Remove `only` for InlayHints. --- test/integrationTests/inlayHints.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index c61c49be6..e28dd762f 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -51,7 +51,7 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { await testAssetWorkspace.cleanupWorkspace(); }); - test.only("Hints retrieved for region", async () => { + test("Hints retrieved for region", async () => { const range = new vscode.Range(new vscode.Position(4, 8), new vscode.Position(15, 85)); const hints : vscode.InlayHint[] = await vscode.commands.executeCommand('vscode.executeInlayHintProvider', fileUri, range); assert.lengthOf(hints, 6); From 5801953a1c542a1b919564247fca73ae9040feaa Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 20:22:01 -0700 Subject: [PATCH 06/12] Ensure inlay hints are enabled in CI. --- test/integrationTests/inlayHints.integration.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index e28dd762f..e2a615d4a 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -24,6 +24,9 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { this.skip(); } + const editorConfig = vscode.workspace.getConfiguration('editor'); + editorConfig.update('inlayHints.enabled', true); + const csharpConfig = vscode.workspace.getConfiguration('csharp'); csharpConfig.update('inlayHints.parameters.enabled', true); csharpConfig.update('inlayHints.parameters.forLiteralParameters', true); From d4abcf22bacd4aaff019c329462d06629ad3f515 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 20:38:59 -0700 Subject: [PATCH 07/12] Set CODE_VERSION to 1.65 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fbba3db9f..f23d1fd64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,8 +43,8 @@ jobs: gulp test npm run test:artifacts env: - CODE_VERSION: 1.45.0 + CODE_VERSION: 1.65.0 DISPLAY: :99.0 - name: Build platform-specific extension package - run: gulp 'vsix:release:package:platform-specific' \ No newline at end of file + run: gulp 'vsix:release:package:platform-specific' From 106820250ada053afc14e41b564ff71f9b9ef36a Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 21:26:32 -0700 Subject: [PATCH 08/12] Fix undefined error for fileOpenClose --- src/features/fileOpenCloseProvider.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/features/fileOpenCloseProvider.ts b/src/features/fileOpenCloseProvider.ts index 3c258fa35..e1e8e7787 100644 --- a/src/features/fileOpenCloseProvider.ts +++ b/src/features/fileOpenCloseProvider.ts @@ -49,8 +49,8 @@ class FileOpenCloseProvider implements IDisposable { await serverUtils.fileClose(this._server, { FileName: e.fileName }); } - private async _onActiveTextEditorChange(e: vscode.TextEditor) { - if (shouldIgnoreDocument(e.document)) { + private async _onActiveTextEditorChange(e: vscode.TextEditor | undefined) { + if (e === undefined || shouldIgnoreDocument(e.document)) { return; } @@ -71,4 +71,4 @@ function shouldIgnoreDocument(document: vscode.TextDocument) { } return false; -} \ No newline at end of file +} From be6149509fa3c935fb26a73f57014373504bce5f Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 23:37:15 -0700 Subject: [PATCH 09/12] Open file. --- test/integrationTests/inlayHints.integration.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index e2a615d4a..50a11a935 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -55,6 +55,7 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { }); test("Hints retrieved for region", async () => { + await vscode.commands.executeCommand("vscode.open", fileUri); const range = new vscode.Range(new vscode.Position(4, 8), new vscode.Position(15, 85)); const hints : vscode.InlayHint[] = await vscode.commands.executeCommand('vscode.executeInlayHintProvider', fileUri, range); assert.lengthOf(hints, 6); From 976b70ab708447648389f665278883b33f33d55e Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Mar 2022 23:44:32 -0700 Subject: [PATCH 10/12] Restart the server. --- test/integrationTests/inlayHints.integration.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index 50a11a935..27d52be2d 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; import { should, assert } from 'chai'; -import { activateCSharpExtension, isRazorWorkspace, isSlnWithGenerator } from './integrationHelpers'; +import { activateCSharpExtension, isRazorWorkspace, isSlnWithGenerator, restartOmniSharpServer } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; import * as path from 'path'; @@ -41,6 +41,7 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { csharpConfig.update('inlayHints.types.forLambdaParameterTypes', true); csharpConfig.update('inlayHints.types.forImplicitObjectCreation', true); + await restartOmniSharpServer(); const activation = await activateCSharpExtension(); await testAssetWorkspace.restoreAndWait(activation); From 9f485d232db96a2931dede3aa56482b810d9702e Mon Sep 17 00:00:00 2001 From: Fred Silberberg Date: Mon, 28 Mar 2022 23:14:38 -0700 Subject: [PATCH 11/12] Apply suggestions from code review Co-authored-by: Joey Robichaud --- test/integrationTests/inlayHints.integration.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index 27d52be2d..7fc79e77c 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -43,12 +43,15 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { await restartOmniSharpServer(); const activation = await activateCSharpExtension(); - await testAssetWorkspace.restoreAndWait(activation); + await testAssetWorkspace.restore(); const fileName = 'inlayHints.cs'; const projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; const filePath = path.join(projectDirectory, fileName); fileUri = vscode.Uri.file(filePath); + + await vscode.commands.executeCommand("vscode.open", fileUri); + await testAssetWorkspace.waitForIdle(activation.eventStream); }); suiteTeardown(async () => { @@ -56,7 +59,6 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { }); test("Hints retrieved for region", async () => { - await vscode.commands.executeCommand("vscode.open", fileUri); const range = new vscode.Range(new vscode.Position(4, 8), new vscode.Position(15, 85)); const hints : vscode.InlayHint[] = await vscode.commands.executeCommand('vscode.executeInlayHintProvider', fileUri, range); assert.lengthOf(hints, 6); From 922792a6efff1e327c6048ae70519f3f75d0a3b1 Mon Sep 17 00:00:00 2001 From: Fred Silberberg Date: Tue, 29 Mar 2022 11:25:18 -0700 Subject: [PATCH 12/12] Await config updates Co-authored-by: Joey Robichaud --- .../inlayHints.integration.test.ts | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/integrationTests/inlayHints.integration.test.ts b/test/integrationTests/inlayHints.integration.test.ts index 7fc79e77c..455fec069 100644 --- a/test/integrationTests/inlayHints.integration.test.ts +++ b/test/integrationTests/inlayHints.integration.test.ts @@ -25,21 +25,21 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () { } const editorConfig = vscode.workspace.getConfiguration('editor'); - editorConfig.update('inlayHints.enabled', true); + await editorConfig.update('inlayHints.enabled', true); const csharpConfig = vscode.workspace.getConfiguration('csharp'); - csharpConfig.update('inlayHints.parameters.enabled', true); - csharpConfig.update('inlayHints.parameters.forLiteralParameters', true); - csharpConfig.update('inlayHints.parameters.forObjectCreationParameters', true); - csharpConfig.update('inlayHints.parameters.forIndexerParameters', true); - csharpConfig.update('inlayHints.parameters.forOtherParameters', true); - csharpConfig.update('inlayHints.parameters.suppressForParametersThatDifferOnlyBySuffix', true); - csharpConfig.update('inlayHints.parameters.suppressForParametersThatMatchMethodIntent', true); - csharpConfig.update('inlayHints.parameters.suppressForParametersThatMatchArgumentName', true); - csharpConfig.update('inlayHints.types.enabled', true); - csharpConfig.update('inlayHints.types.forImplicitVariableTypes', true); - csharpConfig.update('inlayHints.types.forLambdaParameterTypes', true); - csharpConfig.update('inlayHints.types.forImplicitObjectCreation', true); + await csharpConfig.update('inlayHints.parameters.enabled', true); + await csharpConfig.update('inlayHints.parameters.forLiteralParameters', true); + await csharpConfig.update('inlayHints.parameters.forObjectCreationParameters', true); + await csharpConfig.update('inlayHints.parameters.forIndexerParameters', true); + await csharpConfig.update('inlayHints.parameters.forOtherParameters', true); + await csharpConfig.update('inlayHints.parameters.suppressForParametersThatDifferOnlyBySuffix', true); + await csharpConfig.update('inlayHints.parameters.suppressForParametersThatMatchMethodIntent', true); + await csharpConfig.update('inlayHints.parameters.suppressForParametersThatMatchArgumentName', true); + await csharpConfig.update('inlayHints.types.enabled', true); + await csharpConfig.update('inlayHints.types.forImplicitVariableTypes', true); + await csharpConfig.update('inlayHints.types.forLambdaParameterTypes', true); + await csharpConfig.update('inlayHints.types.forImplicitObjectCreation', true); await restartOmniSharpServer(); const activation = await activateCSharpExtension();