Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/common/tokens/tokenWithTextArray.ts
3294 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { OffsetRange } from '../core/ranges/offsetRange.js';
7
import { ILanguageIdCodec } from '../languages.js';
8
import { LineTokens } from './lineTokens.js';
9
10
/**
11
* This class represents a sequence of tokens.
12
* Conceptually, each token has a length and a metadata number.
13
* A token array might be used to annotate a string with metadata.
14
* Use {@link TokenWithTextArrayBuilder} to efficiently create a token array.
15
*
16
* TODO: Make this class more efficient (e.g. by using a Int32Array).
17
*/
18
export class TokenWithTextArray {
19
public static fromLineTokens(lineTokens: LineTokens): TokenWithTextArray {
20
const tokenInfo: TokenWithTextInfo[] = [];
21
for (let i = 0; i < lineTokens.getCount(); i++) {
22
tokenInfo.push(new TokenWithTextInfo(lineTokens.getTokenText(i), lineTokens.getMetadata(i)));
23
}
24
return TokenWithTextArray.create(tokenInfo);
25
}
26
27
public static create(tokenInfo: TokenWithTextInfo[]): TokenWithTextArray {
28
return new TokenWithTextArray(tokenInfo);
29
}
30
31
private constructor(
32
private readonly _tokenInfo: TokenWithTextInfo[],
33
) { }
34
35
public toLineTokens(decoder: ILanguageIdCodec): LineTokens {
36
return LineTokens.createFromTextAndMetadata(this.map((_r, t) => ({ text: t.text, metadata: t.metadata })), decoder);
37
}
38
39
public forEach(cb: (range: OffsetRange, tokenInfo: TokenWithTextInfo) => void): void {
40
let lengthSum = 0;
41
for (const tokenInfo of this._tokenInfo) {
42
const range = new OffsetRange(lengthSum, lengthSum + tokenInfo.text.length);
43
cb(range, tokenInfo);
44
lengthSum += tokenInfo.text.length;
45
}
46
}
47
48
public map<T>(cb: (range: OffsetRange, tokenInfo: TokenWithTextInfo) => T): T[] {
49
const result: T[] = [];
50
let lengthSum = 0;
51
for (const tokenInfo of this._tokenInfo) {
52
const range = new OffsetRange(lengthSum, lengthSum + tokenInfo.text.length);
53
result.push(cb(range, tokenInfo));
54
lengthSum += tokenInfo.text.length;
55
}
56
return result;
57
}
58
59
public slice(range: OffsetRange): TokenWithTextArray {
60
const result: TokenWithTextInfo[] = [];
61
let lengthSum = 0;
62
for (const tokenInfo of this._tokenInfo) {
63
const tokenStart = lengthSum;
64
const tokenEndEx = tokenStart + tokenInfo.text.length;
65
if (tokenEndEx > range.start) {
66
if (tokenStart >= range.endExclusive) {
67
break;
68
}
69
70
const deltaBefore = Math.max(0, range.start - tokenStart);
71
const deltaAfter = Math.max(0, tokenEndEx - range.endExclusive);
72
73
result.push(new TokenWithTextInfo(tokenInfo.text.slice(deltaBefore, tokenInfo.text.length - deltaAfter), tokenInfo.metadata));
74
}
75
76
lengthSum += tokenInfo.text.length;
77
}
78
return TokenWithTextArray.create(result);
79
}
80
81
public append(other: TokenWithTextArray): TokenWithTextArray {
82
const result: TokenWithTextInfo[] = this._tokenInfo.concat(other._tokenInfo);
83
return TokenWithTextArray.create(result);
84
}
85
}
86
87
export type TokenMetadata = number;
88
89
export class TokenWithTextInfo {
90
constructor(
91
public readonly text: string,
92
public readonly metadata: TokenMetadata,
93
) { }
94
}
95
96
/**
97
* TODO: Make this class more efficient (e.g. by using a Int32Array).
98
*/
99
export class TokenWithTextArrayBuilder {
100
private readonly _tokens: TokenWithTextInfo[] = [];
101
102
public add(text: string, metadata: TokenMetadata): void {
103
this._tokens.push(new TokenWithTextInfo(text, metadata));
104
}
105
106
public build(): TokenWithTextArray {
107
return TokenWithTextArray.create(this._tokens);
108
}
109
}
110
111