This commit is contained in:
Alexandru Dima
2019-09-30 15:19:07 +02:00
parent 110b5acf0d
commit 45a92a4937
8 changed files with 440 additions and 33 deletions

View File

@@ -21,6 +21,7 @@ import { Selection } from 'vs/editor/common/core/selection';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import * as callh from 'vs/workbench/contrib/callHierarchy/browser/callHierarchy';
import { mixin } from 'vs/base/common/objects';
import { decodeSemanticTokensDto, ISemanticTokensDto } from 'vs/workbench/api/common/shared/semanticTokens';
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesShape {
@@ -324,6 +325,12 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
}));
}
// --- semantic coloring
$registerSemanticColoringProvider(handle: number, selector: IDocumentFilterDto[], legend: modes.SemanticColoringLegend): void {
this._registrations.set(handle, modes.SemanticColoringProviderRegistry.register(selector, new MainThreadSemanticColoringProvider(this._proxy, handle, legend)));
}
// --- suggest
private static _inflateSuggestDto(defaultRange: IRange, data: ISuggestDataDto): modes.CompletionItem {
@@ -584,3 +591,72 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
}
}
class SemanticColoringCacheEntry implements modes.SemanticColoring {
constructor(
private readonly _parent: MainThreadSemanticColoringProvider,
public readonly uri: URI,
public readonly id: number,
public readonly areas: modes.SemanticColoringArea[],
) {
}
dispose(): void {
this._parent.release(this);
}
}
class MainThreadSemanticColoringProvider implements modes.SemanticColoringProvider {
private readonly _cache = new Map<string, SemanticColoringCacheEntry>();
constructor(
private readonly _proxy: ExtHostLanguageFeaturesShape,
private readonly _handle: number,
private readonly _legend: modes.SemanticColoringLegend,
) {
}
release(entry: SemanticColoringCacheEntry): void {
this._cache.delete(entry.uri.toString());
}
getLegend(): modes.SemanticColoringLegend {
return this._legend;
}
async provideSemanticColoring(model: ITextModel, token: CancellationToken): Promise<modes.SemanticColoring | null> {
const lastResult = this._cache.get(model.uri.toString()) || null;
const encodedDto = await this._proxy.$provideSemanticColoring(this._handle, model.uri, lastResult ? lastResult.id : 0, token);
if (!encodedDto) {
return null;
}
if (token.isCancellationRequested) {
return null;
}
const dto = decodeSemanticTokensDto(encodedDto);
const res = this._createSemanticColoring(model, lastResult, dto);
this._cache.set(model.uri.toString(), res);
return res;
}
private _createSemanticColoring(model: ITextModel, lastResult: SemanticColoringCacheEntry | null, dto: ISemanticTokensDto): SemanticColoringCacheEntry {
let areas: modes.SemanticColoringArea[] = [];
for (let i = 0, len = dto.areas.length; i < len; i++) {
const areaDto = dto.areas[i];
if (areaDto.type === 'full') {
areas[i] = {
line: areaDto.line,
data: areaDto.data
};
} else {
areas[i] = {
line: areaDto.line,
data: lastResult!.areas[areaDto.oldIndex].data
};
}
}
return new SemanticColoringCacheEntry(this, model.uri, dto.id, areas);
}
}