UNPKG

6.34 kBJavaScriptView Raw
1"use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
3var _types = require('./parser/tokenizer/types');
4
5
6
7
8
9
10 class TokenProcessor {
11 __init() {this.resultCode = ""}
12 __init2() {this.tokenIndex = 0}
13
14 constructor(
15 code,
16 tokens,
17 isFlowEnabled,
18 ) {;this.code = code;this.tokens = tokens;this.isFlowEnabled = isFlowEnabled;TokenProcessor.prototype.__init.call(this);TokenProcessor.prototype.__init2.call(this);}
19
20 /**
21 * Make a new TokenProcessor for things like lookahead.
22 */
23 snapshot() {
24 return {resultCode: this.resultCode, tokenIndex: this.tokenIndex};
25 }
26
27 restoreToSnapshot(snapshot) {
28 this.resultCode = snapshot.resultCode;
29 this.tokenIndex = snapshot.tokenIndex;
30 }
31
32 getResultCodeIndex() {
33 return this.resultCode.length;
34 }
35
36 reset() {
37 this.resultCode = "";
38 this.tokenIndex = 0;
39 }
40
41 matchesContextualAtIndex(index, contextualKeyword) {
42 return (
43 this.matches1AtIndex(index, _types.TokenType.name) &&
44 this.tokens[index].contextualKeyword === contextualKeyword
45 );
46 }
47
48 identifierNameAtIndex(index) {
49 // TODO: We need to process escapes since technically you can have unicode escapes in variable
50 // names.
51 return this.identifierNameForToken(this.tokens[index]);
52 }
53
54 identifierName() {
55 return this.identifierNameForToken(this.currentToken());
56 }
57
58 identifierNameForToken(token) {
59 return this.code.slice(token.start, token.end);
60 }
61
62 rawCodeForToken(token) {
63 return this.code.slice(token.start, token.end);
64 }
65
66 stringValueAtIndex(index) {
67 return this.stringValueForToken(this.tokens[index]);
68 }
69
70 stringValue() {
71 return this.stringValueForToken(this.currentToken());
72 }
73
74 stringValueForToken(token) {
75 // This is used to identify when two imports are the same and to resolve TypeScript enum keys.
76 // Ideally we'd process escapes within the strings, but for now we pretty much take the raw
77 // code.
78 return this.code.slice(token.start + 1, token.end - 1);
79 }
80
81 matches1AtIndex(index, t1) {
82 return this.tokens[index].type === t1;
83 }
84
85 matches2AtIndex(index, t1, t2) {
86 return this.tokens[index].type === t1 && this.tokens[index + 1].type === t2;
87 }
88
89 matches3AtIndex(index, t1, t2, t3) {
90 return (
91 this.tokens[index].type === t1 &&
92 this.tokens[index + 1].type === t2 &&
93 this.tokens[index + 2].type === t3
94 );
95 }
96
97 matches1(t1) {
98 return this.tokens[this.tokenIndex].type === t1;
99 }
100
101 matches2(t1, t2) {
102 return this.tokens[this.tokenIndex].type === t1 && this.tokens[this.tokenIndex + 1].type === t2;
103 }
104
105 matches3(t1, t2, t3) {
106 return (
107 this.tokens[this.tokenIndex].type === t1 &&
108 this.tokens[this.tokenIndex + 1].type === t2 &&
109 this.tokens[this.tokenIndex + 2].type === t3
110 );
111 }
112
113 matches4(t1, t2, t3, t4) {
114 return (
115 this.tokens[this.tokenIndex].type === t1 &&
116 this.tokens[this.tokenIndex + 1].type === t2 &&
117 this.tokens[this.tokenIndex + 2].type === t3 &&
118 this.tokens[this.tokenIndex + 3].type === t4
119 );
120 }
121
122 matches5(t1, t2, t3, t4, t5) {
123 return (
124 this.tokens[this.tokenIndex].type === t1 &&
125 this.tokens[this.tokenIndex + 1].type === t2 &&
126 this.tokens[this.tokenIndex + 2].type === t3 &&
127 this.tokens[this.tokenIndex + 3].type === t4 &&
128 this.tokens[this.tokenIndex + 4].type === t5
129 );
130 }
131
132 matchesContextual(contextualKeyword) {
133 return this.matchesContextualAtIndex(this.tokenIndex, contextualKeyword);
134 }
135
136 matchesContextIdAndLabel(type, contextId) {
137 return this.matches1(type) && this.currentToken().contextId === contextId;
138 }
139
140 previousWhitespaceAndComments() {
141 let whitespaceAndComments = this.code.slice(
142 this.tokenIndex > 0 ? this.tokens[this.tokenIndex - 1].end : 0,
143 this.tokenIndex < this.tokens.length ? this.tokens[this.tokenIndex].start : this.code.length,
144 );
145 if (this.isFlowEnabled) {
146 whitespaceAndComments = whitespaceAndComments.replace(/@flow/g, "");
147 }
148 return whitespaceAndComments;
149 }
150
151 replaceToken(newCode) {
152 this.resultCode += this.previousWhitespaceAndComments();
153 this.resultCode += newCode;
154 this.tokenIndex++;
155 }
156
157 replaceTokenTrimmingLeftWhitespace(newCode) {
158 this.resultCode += this.previousWhitespaceAndComments().replace(/[^\r\n]/g, "");
159 this.resultCode += newCode;
160 this.tokenIndex++;
161 }
162
163 removeInitialToken() {
164 this.replaceToken("");
165 }
166
167 removeToken() {
168 this.replaceTokenTrimmingLeftWhitespace("");
169 }
170
171 copyExpectedToken(tokenType) {
172 if (this.tokens[this.tokenIndex].type !== tokenType) {
173 throw new Error(`Expected token ${tokenType}`);
174 }
175 this.copyToken();
176 }
177
178 copyToken() {
179 this.resultCode += this.previousWhitespaceAndComments();
180 this.resultCode += this.code.slice(
181 this.tokens[this.tokenIndex].start,
182 this.tokens[this.tokenIndex].end,
183 );
184 this.tokenIndex++;
185 }
186
187 copyTokenWithPrefix(prefix) {
188 this.resultCode += this.previousWhitespaceAndComments();
189 this.resultCode += prefix;
190 this.resultCode += this.code.slice(
191 this.tokens[this.tokenIndex].start,
192 this.tokens[this.tokenIndex].end,
193 );
194 this.tokenIndex++;
195 }
196
197 appendCode(code) {
198 this.resultCode += code;
199 }
200
201 currentToken() {
202 return this.tokens[this.tokenIndex];
203 }
204
205 currentTokenCode() {
206 const token = this.currentToken();
207 return this.code.slice(token.start, token.end);
208 }
209
210 tokenAtRelativeIndex(relativeIndex) {
211 return this.tokens[this.tokenIndex + relativeIndex];
212 }
213
214 currentIndex() {
215 return this.tokenIndex;
216 }
217
218 /**
219 * Move to the next token. Only suitable in preprocessing steps. When
220 * generating new code, you should use copyToken or removeToken.
221 */
222 nextToken() {
223 if (this.tokenIndex === this.tokens.length) {
224 throw new Error("Unexpectedly reached end of input.");
225 }
226 this.tokenIndex++;
227 }
228
229 previousToken() {
230 this.tokenIndex--;
231 }
232
233 finish() {
234 if (this.tokenIndex !== this.tokens.length) {
235 throw new Error("Tried to finish processing tokens before reaching the end.");
236 }
237 this.resultCode += this.previousWhitespaceAndComments();
238 return this.resultCode;
239 }
240
241 isAtEnd() {
242 return this.tokenIndex === this.tokens.length;
243 }
244} exports.default = TokenProcessor;