UNPKG

6.24 kBJavaScriptView Raw
1"use strict";
2/* --------------------------------------------------------------------------------------------
3 * Copyright (c) Microsoft Corporation. All rights reserved.
4 * Licensed under the MIT License. See License.txt in the project root for license information.
5 * ------------------------------------------------------------------------------------------ */
6Object.defineProperty(exports, "__esModule", { value: true });
7exports.SemanticTokensBuilder = exports.SemanticTokensDiff = exports.SemanticTokensFeature = void 0;
8const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
9const SemanticTokensFeature = (Base) => {
10 return class extends Base {
11 get semanticTokens() {
12 return {
13 refresh: () => {
14 return this.connection.sendRequest(vscode_languageserver_protocol_1.SemanticTokensRefreshRequest.type);
15 },
16 on: (handler) => {
17 const type = vscode_languageserver_protocol_1.SemanticTokensRequest.type;
18 return this.connection.onRequest(type, (params, cancel) => {
19 return handler(params, cancel, this.attachWorkDoneProgress(params), this.attachPartialResultProgress(type, params));
20 });
21 },
22 onDelta: (handler) => {
23 const type = vscode_languageserver_protocol_1.SemanticTokensDeltaRequest.type;
24 return this.connection.onRequest(type, (params, cancel) => {
25 return handler(params, cancel, this.attachWorkDoneProgress(params), this.attachPartialResultProgress(type, params));
26 });
27 },
28 onRange: (handler) => {
29 const type = vscode_languageserver_protocol_1.SemanticTokensRangeRequest.type;
30 return this.connection.onRequest(type, (params, cancel) => {
31 return handler(params, cancel, this.attachWorkDoneProgress(params), this.attachPartialResultProgress(type, params));
32 });
33 }
34 };
35 }
36 };
37};
38exports.SemanticTokensFeature = SemanticTokensFeature;
39class SemanticTokensDiff {
40 constructor(originalSequence, modifiedSequence) {
41 this.originalSequence = originalSequence;
42 this.modifiedSequence = modifiedSequence;
43 }
44 computeDiff() {
45 const originalLength = this.originalSequence.length;
46 const modifiedLength = this.modifiedSequence.length;
47 let startIndex = 0;
48 while (startIndex < modifiedLength && startIndex < originalLength && this.originalSequence[startIndex] === this.modifiedSequence[startIndex]) {
49 startIndex++;
50 }
51 if (startIndex < modifiedLength && startIndex < originalLength) {
52 let originalEndIndex = originalLength - 1;
53 let modifiedEndIndex = modifiedLength - 1;
54 while (originalEndIndex >= startIndex && modifiedEndIndex >= startIndex && this.originalSequence[originalEndIndex] === this.modifiedSequence[modifiedEndIndex]) {
55 originalEndIndex--;
56 modifiedEndIndex--;
57 }
58 // if one moved behind the start index move them forward again
59 if (originalEndIndex < startIndex || modifiedEndIndex < startIndex) {
60 originalEndIndex++;
61 modifiedEndIndex++;
62 }
63 const deleteCount = originalEndIndex - startIndex + 1;
64 const newData = this.modifiedSequence.slice(startIndex, modifiedEndIndex + 1);
65 // If we moved behind the start index we could have missed a simple delete.
66 if (newData.length === 1 && newData[0] === this.originalSequence[originalEndIndex]) {
67 return [
68 { start: startIndex, deleteCount: deleteCount - 1 }
69 ];
70 }
71 else {
72 return [
73 { start: startIndex, deleteCount, data: newData }
74 ];
75 }
76 }
77 else if (startIndex < modifiedLength) {
78 return [
79 { start: startIndex, deleteCount: 0, data: this.modifiedSequence.slice(startIndex) }
80 ];
81 }
82 else if (startIndex < originalLength) {
83 return [
84 { start: startIndex, deleteCount: originalLength - startIndex }
85 ];
86 }
87 else {
88 // The two arrays are the same.
89 return [];
90 }
91 }
92}
93exports.SemanticTokensDiff = SemanticTokensDiff;
94class SemanticTokensBuilder {
95 constructor() {
96 this._prevData = undefined;
97 this.initialize();
98 }
99 initialize() {
100 this._id = Date.now();
101 this._prevLine = 0;
102 this._prevChar = 0;
103 this._data = [];
104 this._dataLen = 0;
105 }
106 push(line, char, length, tokenType, tokenModifiers) {
107 let pushLine = line;
108 let pushChar = char;
109 if (this._dataLen > 0) {
110 pushLine -= this._prevLine;
111 if (pushLine === 0) {
112 pushChar -= this._prevChar;
113 }
114 }
115 this._data[this._dataLen++] = pushLine;
116 this._data[this._dataLen++] = pushChar;
117 this._data[this._dataLen++] = length;
118 this._data[this._dataLen++] = tokenType;
119 this._data[this._dataLen++] = tokenModifiers;
120 this._prevLine = line;
121 this._prevChar = char;
122 }
123 get id() {
124 return this._id.toString();
125 }
126 previousResult(id) {
127 if (this.id === id) {
128 this._prevData = this._data;
129 }
130 this.initialize();
131 }
132 build() {
133 this._prevData = undefined;
134 return {
135 resultId: this.id,
136 data: this._data
137 };
138 }
139 canBuildEdits() {
140 return this._prevData !== undefined;
141 }
142 buildEdits() {
143 if (this._prevData !== undefined) {
144 return {
145 resultId: this.id,
146 edits: (new SemanticTokensDiff(this._prevData, this._data)).computeDiff()
147 };
148 }
149 else {
150 return this.build();
151 }
152 }
153}
154exports.SemanticTokensBuilder = SemanticTokensBuilder;