mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-20 08:38:56 +01:00
Fix issue with appended deltas having the wrong order & add unit tests to semantic areas delta computation
This commit is contained in:
@@ -622,12 +622,6 @@ const enum SemanticColoringConstants {
|
||||
*/
|
||||
DesiredTokensPerArea = 400,
|
||||
|
||||
/**
|
||||
* If the semantic coloring result contains a single area and the area contains
|
||||
* more than 600 tokens, then split the area into mulitple areas.
|
||||
*/
|
||||
SplitSingleAreaTokenCountThreshold = 600,
|
||||
|
||||
/**
|
||||
* Try to keep the total number of areas under 1024 if possible,
|
||||
* simply compensate by having more tokens per area...
|
||||
@@ -640,15 +634,21 @@ interface ISemanticColoringAreaPair {
|
||||
dto: ISemanticTokensAreaDto;
|
||||
}
|
||||
|
||||
class SemanticColoringAdapter {
|
||||
export class SemanticColoringAdapter {
|
||||
|
||||
private readonly _previousResults = new Map<number, Uint32Array[]>();
|
||||
private readonly _previousResults: Map<number, Uint32Array[]>;
|
||||
private readonly _splitSingleAreaTokenCountThreshold: number;
|
||||
private _nextResultId = 1;
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.SemanticColoringProvider,
|
||||
) { }
|
||||
private readonly _desiredTokensPerArea = SemanticColoringConstants.DesiredTokensPerArea,
|
||||
private readonly _desiredMaxAreas = SemanticColoringConstants.DesiredMaxAreas
|
||||
) {
|
||||
this._previousResults = new Map<number, Uint32Array[]>();
|
||||
this._splitSingleAreaTokenCountThreshold = Math.round(1.5 * this._desiredTokensPerArea);
|
||||
}
|
||||
|
||||
provideSemanticColoring(resource: URI, previousSemanticColoringResultId: number, token: CancellationToken): Promise<VSBuffer | null> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
@@ -736,7 +736,6 @@ class SemanticColoringAdapter {
|
||||
}
|
||||
|
||||
private _deltaEncodeArea(oldAreas: Uint32Array[], newArea: SemanticColoringArea): VSBuffer {
|
||||
console.log(`_deltaEncodeArea`);
|
||||
const newAreaData = newArea.data;
|
||||
const prependAreas: ISemanticColoringAreaPair[] = [];
|
||||
const appendAreas: ISemanticColoringAreaPair[] = [];
|
||||
@@ -748,7 +747,7 @@ class SemanticColoringAdapter {
|
||||
const oldAreaData = oldAreas[i];
|
||||
const oldAreaTokenCount = (oldAreaData.length / 5) | 0;
|
||||
if (newTokenEndIndex - newTokenStartIndex < oldAreaTokenCount) {
|
||||
// thre are too many old tokens, this cannot work
|
||||
// there are too many old tokens, this cannot work
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -786,7 +785,7 @@ class SemanticColoringAdapter {
|
||||
}
|
||||
newTokenEndIndex -= oldAreaTokenCount;
|
||||
|
||||
appendAreas.push({
|
||||
appendAreas.unshift({
|
||||
data: oldAreaData,
|
||||
dto: {
|
||||
type: 'delta',
|
||||
@@ -798,18 +797,14 @@ class SemanticColoringAdapter {
|
||||
|
||||
if (prependAreas.length === 0 && appendAreas.length === 0) {
|
||||
// There is no reuse possibility!
|
||||
console.log(`no reuse possibility`);
|
||||
return this._fullEncodeAreas([newArea]);
|
||||
}
|
||||
|
||||
if (newTokenStartIndex === newTokenEndIndex) {
|
||||
// 100% reuse!
|
||||
console.log(`100% reuse`);
|
||||
return this._saveResultAndEncode(prependAreas.concat(appendAreas));
|
||||
}
|
||||
|
||||
console.log(`some reuse`);
|
||||
|
||||
// Extract the mid area
|
||||
const newTokenStartDeltaLine = newAreaData[5 * newTokenStartIndex];
|
||||
const newMidAreaData = new Uint32Array(5 * (newTokenEndIndex - newTokenStartIndex));
|
||||
@@ -830,7 +825,7 @@ class SemanticColoringAdapter {
|
||||
}
|
||||
|
||||
const newMidArea = new SemanticColoringArea(newArea.line + newTokenStartDeltaLine, newMidAreaData);
|
||||
const newMidAreas = SemanticColoringAdapter._splitAreaIntoMultipleAreasIfNecessary(newMidArea);
|
||||
const newMidAreas = this._splitAreaIntoMultipleAreasIfNecessary(newMidArea);
|
||||
const newMidAreasPairs: ISemanticColoringAreaPair[] = newMidAreas.map(a => {
|
||||
return {
|
||||
data: a.data,
|
||||
@@ -869,9 +864,8 @@ class SemanticColoringAdapter {
|
||||
// }
|
||||
|
||||
private _fullEncodeAreas(areas: SemanticColoringArea[]): VSBuffer {
|
||||
console.log(`_fullEncodeAreas`);
|
||||
if (areas.length === 1) {
|
||||
areas = SemanticColoringAdapter._splitAreaIntoMultipleAreasIfNecessary(areas[0]);
|
||||
areas = this._splitAreaIntoMultipleAreasIfNecessary(areas[0]);
|
||||
}
|
||||
|
||||
return this._saveResultAndEncode(areas.map(a => {
|
||||
@@ -897,15 +891,15 @@ class SemanticColoringAdapter {
|
||||
return encodeSemanticTokensDto(dto);
|
||||
}
|
||||
|
||||
private static _splitAreaIntoMultipleAreasIfNecessary(area: vscode.SemanticColoringArea): SemanticColoringArea[] {
|
||||
private _splitAreaIntoMultipleAreasIfNecessary(area: vscode.SemanticColoringArea): SemanticColoringArea[] {
|
||||
const srcAreaLine = area.line;
|
||||
const srcAreaData = area.data;
|
||||
const tokenCount = (srcAreaData.length / 5) | 0;
|
||||
if (tokenCount <= SemanticColoringConstants.SplitSingleAreaTokenCountThreshold) {
|
||||
if (tokenCount <= this._splitSingleAreaTokenCountThreshold) {
|
||||
return [area];
|
||||
}
|
||||
|
||||
const tokensPerArea = Math.max(Math.ceil(tokenCount / SemanticColoringConstants.DesiredMaxAreas), SemanticColoringConstants.DesiredTokensPerArea);
|
||||
const tokensPerArea = Math.max(Math.ceil(tokenCount / this._desiredMaxAreas), this._desiredTokensPerArea);
|
||||
|
||||
let result: SemanticColoringArea[] = [];
|
||||
let tokenIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user