mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 01:58:53 +01:00
SemanticTokens - implement feedback received in API call:
- extract a separate DocumentRangeSemanticTokensProvider that deals with a document range - extract a separate provideDocumentSemanticTokensEdits that deals with updating via SemanticTokensEdits a previous result
This commit is contained in:
@@ -379,9 +379,13 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable {
|
||||
return extHostLanguageFeatures.registerOnTypeFormattingEditProvider(extension, checkSelector(selector), provider, [firstTriggerCharacter].concat(moreTriggerCharacters));
|
||||
},
|
||||
registerSemanticTokensProvider(selector: vscode.DocumentSelector, provider: vscode.SemanticTokensProvider, legend: vscode.SemanticTokensLegend): vscode.Disposable {
|
||||
registerDocumentSemanticTokensProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSemanticTokensProvider, legend: vscode.SemanticTokensLegend): vscode.Disposable {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostLanguageFeatures.registerSemanticTokensProvider(extension, checkSelector(selector), provider, legend);
|
||||
return extHostLanguageFeatures.registerDocumentSemanticTokensProvider(extension, checkSelector(selector), provider, legend);
|
||||
},
|
||||
registerDocumentRangeSemanticTokensProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeSemanticTokensProvider, legend: vscode.SemanticTokensLegend): vscode.Disposable {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostLanguageFeatures.registerDocumentRangeSemanticTokensProvider(extension, checkSelector(selector), provider, legend);
|
||||
},
|
||||
registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, firstItem?: string | vscode.SignatureHelpProviderMetadata, ...remaining: string[]): vscode.Disposable {
|
||||
if (typeof firstItem === 'object') {
|
||||
|
||||
@@ -358,7 +358,8 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
||||
$registerOnTypeFormattingSupport(handle: number, selector: IDocumentFilterDto[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void;
|
||||
$registerNavigateTypeSupport(handle: number): void;
|
||||
$registerRenameSupport(handle: number, selector: IDocumentFilterDto[], supportsResolveInitialValues: boolean): void;
|
||||
$registerSemanticTokensProvider(handle: number, selector: IDocumentFilterDto[], legend: modes.SemanticTokensLegend): void;
|
||||
$registerDocumentSemanticTokensProvider(handle: number, selector: IDocumentFilterDto[], legend: modes.SemanticTokensLegend): void;
|
||||
$registerDocumentRangeSemanticTokensProvider(handle: number, selector: IDocumentFilterDto[], legend: modes.SemanticTokensLegend): void;
|
||||
$registerSuggestSupport(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void;
|
||||
$registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void;
|
||||
$registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void;
|
||||
@@ -1188,8 +1189,9 @@ export interface ExtHostLanguageFeaturesShape {
|
||||
$releaseWorkspaceSymbols(handle: number, id: number): void;
|
||||
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<IWorkspaceEditDto | undefined>;
|
||||
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation | undefined>;
|
||||
$provideSemanticTokens(handle: number, resource: UriComponents, ranges: IRange[] | null, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null>;
|
||||
$releaseSemanticTokens(handle: number, semanticColoringResultId: number): void;
|
||||
$provideDocumentSemanticTokens(handle: number, resource: UriComponents, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null>;
|
||||
$releaseDocumentSemanticTokens(handle: number, semanticColoringResultId: number): void;
|
||||
$provideDocumentRangeSemanticTokens(handle: number, resource: UriComponents, range: IRange, token: CancellationToken): Promise<VSBuffer | null>;
|
||||
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<ISuggestResultDto | undefined>;
|
||||
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise<ISuggestDataDto | undefined>;
|
||||
$releaseCompletionItems(handle: number, id: number): void;
|
||||
|
||||
@@ -629,37 +629,38 @@ class SemanticTokensPreviousResult {
|
||||
) { }
|
||||
}
|
||||
|
||||
export class SemanticTokensAdapter {
|
||||
export class DocumentSemanticTokensAdapter {
|
||||
|
||||
private readonly _previousResults: Map<number, SemanticTokensPreviousResult>;
|
||||
private _nextResultId = 1;
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.SemanticTokensProvider,
|
||||
private readonly _provider: vscode.DocumentSemanticTokensProvider,
|
||||
) {
|
||||
this._previousResults = new Map<number, SemanticTokensPreviousResult>();
|
||||
}
|
||||
|
||||
provideSemanticTokens(resource: URI, ranges: IRange[] | null, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null> {
|
||||
provideDocumentSemanticTokens(resource: URI, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const previousResult = (previousResultId !== 0 ? this._previousResults.get(previousResultId) : null);
|
||||
const opts: vscode.SemanticTokensRequestOptions = {
|
||||
ranges: (Array.isArray(ranges) && ranges.length > 0 ? ranges.map<Range>(typeConvert.Range.to) : undefined),
|
||||
previousResultId: (previousResult ? previousResult.resultId : undefined)
|
||||
};
|
||||
return asPromise(() => this._provider.provideSemanticTokens(doc, opts, token)).then(value => {
|
||||
if (!value) {
|
||||
return null;
|
||||
return asPromise(() => {
|
||||
if (previousResult && typeof previousResult.resultId === 'string' && typeof this._provider.provideDocumentSemanticTokensEdits === 'function') {
|
||||
return this._provider.provideDocumentSemanticTokensEdits(doc, previousResult.resultId, token);
|
||||
}
|
||||
return this._provider.provideDocumentSemanticTokens(doc, token);
|
||||
}).then(value => {
|
||||
if (previousResult) {
|
||||
this._previousResults.delete(previousResultId);
|
||||
}
|
||||
return this._send(SemanticTokensAdapter._convertToEdits(previousResult, value), value);
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
return this._send(DocumentSemanticTokensAdapter._convertToEdits(previousResult, value), value);
|
||||
});
|
||||
}
|
||||
|
||||
async releaseSemanticColoring(semanticColoringResultId: number): Promise<void> {
|
||||
async releaseDocumentSemanticColoring(semanticColoringResultId: number): Promise<void> {
|
||||
this._previousResults.delete(semanticColoringResultId);
|
||||
}
|
||||
|
||||
@@ -672,7 +673,7 @@ export class SemanticTokensAdapter {
|
||||
}
|
||||
|
||||
private static _convertToEdits(previousResult: SemanticTokensPreviousResult | null | undefined, newResult: vscode.SemanticTokens | vscode.SemanticTokensEdits): vscode.SemanticTokens | vscode.SemanticTokensEdits {
|
||||
if (!SemanticTokensAdapter._isSemanticTokens(newResult)) {
|
||||
if (!DocumentSemanticTokensAdapter._isSemanticTokens(newResult)) {
|
||||
return newResult;
|
||||
}
|
||||
if (!previousResult || !previousResult.tokens) {
|
||||
@@ -708,7 +709,7 @@ export class SemanticTokensAdapter {
|
||||
}
|
||||
|
||||
private _send(value: vscode.SemanticTokens | vscode.SemanticTokensEdits, original: vscode.SemanticTokens | vscode.SemanticTokensEdits): VSBuffer | null {
|
||||
if (SemanticTokensAdapter._isSemanticTokens(value)) {
|
||||
if (DocumentSemanticTokensAdapter._isSemanticTokens(value)) {
|
||||
const myId = this._nextResultId++;
|
||||
this._previousResults.set(myId, new SemanticTokensPreviousResult(value.resultId, value.data));
|
||||
return encodeSemanticTokensDto({
|
||||
@@ -718,9 +719,9 @@ export class SemanticTokensAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
if (SemanticTokensAdapter._isSemanticTokensEdits(value)) {
|
||||
if (DocumentSemanticTokensAdapter._isSemanticTokensEdits(value)) {
|
||||
const myId = this._nextResultId++;
|
||||
if (SemanticTokensAdapter._isSemanticTokens(original)) {
|
||||
if (DocumentSemanticTokensAdapter._isSemanticTokens(original)) {
|
||||
// store the original
|
||||
this._previousResults.set(myId, new SemanticTokensPreviousResult(original.resultId, original.data));
|
||||
} else {
|
||||
@@ -737,6 +738,33 @@ export class SemanticTokensAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
export class DocumentRangeSemanticTokensAdapter {
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.DocumentRangeSemanticTokensProvider,
|
||||
) {
|
||||
}
|
||||
|
||||
provideDocumentRangeSemanticTokens(resource: URI, range: IRange, token: CancellationToken): Promise<VSBuffer | null> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
return asPromise(() => this._provider.provideDocumentRangeSemanticTokens(doc, typeConvert.Range.to(range), token)).then(value => {
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
return this._send(value);
|
||||
});
|
||||
}
|
||||
|
||||
private _send(value: vscode.SemanticTokens): VSBuffer | null {
|
||||
return encodeSemanticTokensDto({
|
||||
id: 0,
|
||||
type: 'full',
|
||||
data: value.data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class SuggestAdapter {
|
||||
|
||||
static supportsResolving(provider: vscode.CompletionItemProvider): boolean {
|
||||
@@ -1324,9 +1352,9 @@ class CallHierarchyAdapter {
|
||||
type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentFormattingAdapter
|
||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||
| SemanticTokensAdapter | SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter
|
||||
| ImplementationAdapter | TypeDefinitionAdapter | ColorProviderAdapter | FoldingProviderAdapter
|
||||
| DeclarationAdapter | SelectionRangeAdapter | CallHierarchyAdapter;
|
||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter
|
||||
| TypeDefinitionAdapter | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter
|
||||
| SelectionRangeAdapter | CallHierarchyAdapter | DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter;
|
||||
|
||||
class AdapterData {
|
||||
constructor(
|
||||
@@ -1657,18 +1685,28 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
|
||||
//#region semantic coloring
|
||||
|
||||
registerSemanticTokensProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SemanticTokensProvider, legend: vscode.SemanticTokensLegend): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new SemanticTokensAdapter(this._documents, provider), extension);
|
||||
this._proxy.$registerSemanticTokensProvider(handle, this._transformDocumentSelector(selector), legend);
|
||||
registerDocumentSemanticTokensProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentSemanticTokensProvider, legend: vscode.SemanticTokensLegend): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new DocumentSemanticTokensAdapter(this._documents, provider), extension);
|
||||
this._proxy.$registerDocumentSemanticTokensProvider(handle, this._transformDocumentSelector(selector), legend);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideSemanticTokens(handle: number, resource: UriComponents, ranges: IRange[] | null, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null> {
|
||||
return this._withAdapter(handle, SemanticTokensAdapter, adapter => adapter.provideSemanticTokens(URI.revive(resource), ranges, previousResultId, token), null);
|
||||
$provideDocumentSemanticTokens(handle: number, resource: UriComponents, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null> {
|
||||
return this._withAdapter(handle, DocumentSemanticTokensAdapter, adapter => adapter.provideDocumentSemanticTokens(URI.revive(resource), previousResultId, token), null);
|
||||
}
|
||||
|
||||
$releaseSemanticTokens(handle: number, semanticColoringResultId: number): void {
|
||||
this._withAdapter(handle, SemanticTokensAdapter, adapter => adapter.releaseSemanticColoring(semanticColoringResultId), undefined);
|
||||
$releaseDocumentSemanticTokens(handle: number, semanticColoringResultId: number): void {
|
||||
this._withAdapter(handle, DocumentSemanticTokensAdapter, adapter => adapter.releaseDocumentSemanticColoring(semanticColoringResultId), undefined);
|
||||
}
|
||||
|
||||
registerDocumentRangeSemanticTokensProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentRangeSemanticTokensProvider, legend: vscode.SemanticTokensLegend): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new DocumentRangeSemanticTokensAdapter(this._documents, provider), extension);
|
||||
this._proxy.$registerDocumentRangeSemanticTokensProvider(handle, this._transformDocumentSelector(selector), legend);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentRangeSemanticTokens(handle: number, resource: UriComponents, range: IRange, token: CancellationToken): Promise<VSBuffer | null> {
|
||||
return this._withAdapter(handle, DocumentRangeSemanticTokensAdapter, adapter => adapter.provideDocumentRangeSemanticTokens(URI.revive(resource), range, token), null);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
Reference in New Issue
Block a user