-
Notifications
You must be signed in to change notification settings - Fork 31.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ts inline hints #113412
Merged
Merged
Add ts inline hints #113412
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
a94ed00
Add ts server for inline hints
Kingwl 6bf8b9d
Add some feature related configure
Kingwl 65d2a64
Add more config
Kingwl 5a760dd
Rename all options
Kingwl 3944756
Support range
Kingwl 396dbbb
use new interface
Kingwl 66ff1fa
Fix cr issues
Kingwl ca600b0
Merge branch 'master' into Add_ts_inline_hints
Kingwl af45892
Merge branch 'main' into Add_ts_inline_hints
Kingwl 5302ebb
Merge branch 'main' into Add_ts_inline_hints
Kingwl 7b0cb49
Update inlay hints for ts plugin
Kingwl b24a241
Avoid call chain hints
Kingwl b914b0b
Avoid more option
Kingwl 51612e8
Merge branch 'main' into Add_ts_inline_hints
Kingwl b932538
Merge branch 'main' into Add_ts_inline_hints
Kingwl 4b0e101
Update protos
Kingwl bf6579e
Update extensions/typescript-language-features/package.nls.json
Kingwl c485647
Use suppress for some option
Kingwl 5b77ff6
Merge branch 'main' into Add_ts_inline_hints
Kingwl 2a6f9da
Update CR issues
Kingwl af1b51a
Fix missing typedef
Kingwl 16b2ff1
Avoid changes
Kingwl ead709b
Merge branch 'main' into Add_ts_inline_hints
Kingwl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
extensions/typescript-language-features/src/languageFeatures/inlayHints.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* 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 * as Proto from '../protocol'; | ||
import { DocumentSelector } from '../utils/documentSelector'; | ||
import { ClientCapability, ITypeScriptServiceClient, ServerResponse, ExecConfig } from '../typescriptService'; | ||
import { Condition, conditionalRegistration, requireMinVersion, requireSomeCapability } from '../utils/dependentRegistration'; | ||
import { Position } from '../utils/typeConverters'; | ||
import FileConfigurationManager, { getInlayHintsPreferences } from './fileConfigurationManager'; | ||
import API from '../utils/api'; | ||
|
||
namespace ExperimentalProto { | ||
export const enum CommandTypes { | ||
ProvideInlineHints = 'ProvideInlayHints' | ||
} | ||
|
||
export interface InlayHintsArgs extends Proto.FileRequestArgs { | ||
/** | ||
* Start position of the span. | ||
*/ | ||
start: number; | ||
/** | ||
* Length of the span. | ||
*/ | ||
length: number; | ||
} | ||
|
||
export interface InlineHintsRequest extends Proto.Request { | ||
command: CommandTypes.ProvideInlineHints; | ||
arguments: InlayHintsArgs; | ||
} | ||
|
||
export enum InlayHintKind { | ||
Type = 'Type', | ||
Parameter = 'Parameter', | ||
Enum = 'Enum' | ||
} | ||
|
||
interface InlayHintItem { | ||
text: string; | ||
position: Proto.Location; | ||
kind?: InlayHintKind; | ||
whitespaceBefore?: boolean; | ||
whitespaceAfter?: boolean; | ||
} | ||
|
||
export interface InlayHintsResponse extends Proto.Response { | ||
body?: InlayHintItem[]; | ||
} | ||
|
||
export interface IExtendedTypeScriptServiceClient { | ||
execute<K extends keyof ExtendedTsServerRequests>( | ||
command: K, | ||
args: ExtendedTsServerRequests[K][0], | ||
token: vscode.CancellationToken, | ||
config?: ExecConfig | ||
): Promise<ServerResponse.Response<ExtendedTsServerRequests[K][1]>>; | ||
} | ||
|
||
export interface ExtendedTsServerRequests { | ||
'provideInlayHints': [InlayHintsArgs, InlayHintsResponse]; | ||
} | ||
|
||
export namespace InlayHintKind { | ||
export function fromProtocolInlayHintKind(kind: InlayHintKind): vscode.InlayHintKind { | ||
switch (kind) { | ||
case InlayHintKind.Parameter: | ||
return vscode.InlayHintKind.Parameter; | ||
case InlayHintKind.Type: | ||
return vscode.InlayHintKind.Type; | ||
case InlayHintKind.Enum: | ||
return vscode.InlayHintKind.Other; | ||
default: | ||
return vscode.InlayHintKind.Other; | ||
} | ||
} | ||
} | ||
} | ||
|
||
class TypeScriptInlayHintsProvider implements vscode.InlayHintsProvider { | ||
public static readonly minVersion = API.v440; | ||
|
||
constructor( | ||
private readonly client: ITypeScriptServiceClient, | ||
private readonly fileConfigurationManager: FileConfigurationManager | ||
) { } | ||
|
||
async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise<vscode.InlayHint[]> { | ||
const filepath = this.client.toOpenedFilePath(model); | ||
if (!filepath) { | ||
return []; | ||
} | ||
|
||
await this.fileConfigurationManager.ensureConfigurationForDocument(model, token); | ||
|
||
const start = model.offsetAt(range.start); | ||
const length = model.offsetAt(range.end) - start; | ||
|
||
const response = await (this.client as ExperimentalProto.IExtendedTypeScriptServiceClient).execute('provideInlayHints', { file: filepath, start, length }, token); | ||
if (response.type !== 'response' || !response.success || !response.body) { | ||
return []; | ||
} | ||
|
||
return response.body.map(hint => { | ||
const result = new vscode.InlayHint( | ||
hint.text, | ||
Position.fromLocation(hint.position), | ||
hint.kind && ExperimentalProto.InlayHintKind.fromProtocolInlayHintKind(hint.kind) | ||
); | ||
result.whitespaceBefore = hint.whitespaceBefore; | ||
result.whitespaceAfter = hint.whitespaceAfter; | ||
return result; | ||
}); | ||
} | ||
} | ||
|
||
export function requireInlayHintsConfiguration( | ||
language: string | ||
) { | ||
return new Condition( | ||
() => { | ||
const config = vscode.workspace.getConfiguration(language, null); | ||
const preferences = getInlayHintsPreferences(config); | ||
|
||
return preferences.includeInlayParameterNameHints === 'literals' || | ||
preferences.includeInlayParameterNameHints === 'all' || | ||
preferences.includeInlayEnumMemberValueHints || | ||
preferences.includeInlayFunctionLikeReturnTypeHints || | ||
preferences.includeInlayFunctionParameterTypeHints || | ||
preferences.includeInlayPropertyDeclarationTypeHints || | ||
preferences.includeInlayVariableTypeHints; | ||
}, | ||
vscode.workspace.onDidChangeConfiguration | ||
); | ||
} | ||
|
||
export function register( | ||
selector: DocumentSelector, | ||
modeId: string, | ||
client: ITypeScriptServiceClient, | ||
fileConfigurationManager: FileConfigurationManager | ||
) { | ||
return conditionalRegistration([ | ||
requireInlayHintsConfiguration(modeId), | ||
requireMinVersion(client, TypeScriptInlayHintsProvider.minVersion), | ||
requireSomeCapability(client, ClientCapability.Semantic), | ||
], () => { | ||
return vscode.languages.registerInlayHintsProvider(selector.semantic, | ||
new TypeScriptInlayHintsProvider(client, fileConfigurationManager)); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add descriptions for these too.
@DanielRosenwasser, can you think of a more approachable way to describe this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess if we can’t find a concise way to explain what literal expressions are or are not, these descriptions don’t add much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.