1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | "use strict";
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | const ts = require("typescript"),
|
15 | unescape = require("lodash.unescape");
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | const SyntaxKind = ts.SyntaxKind;
|
22 |
|
23 | const ASSIGNMENT_OPERATORS = [
|
24 | SyntaxKind.EqualsToken,
|
25 | SyntaxKind.PlusEqualsToken,
|
26 | SyntaxKind.MinusEqualsToken,
|
27 | SyntaxKind.AsteriskEqualsToken,
|
28 | SyntaxKind.SlashEqualsToken,
|
29 | SyntaxKind.PercentEqualsToken,
|
30 | SyntaxKind.LessThanLessThanEqualsToken,
|
31 | SyntaxKind.GreaterThanGreaterThanEqualsToken,
|
32 | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken,
|
33 | SyntaxKind.AmpersandEqualsToken,
|
34 | SyntaxKind.BarEqualsToken,
|
35 | SyntaxKind.CaretEqualsToken
|
36 | ];
|
37 |
|
38 | const LOGICAL_OPERATORS = [
|
39 | SyntaxKind.BarBarToken,
|
40 | SyntaxKind.AmpersandAmpersandToken
|
41 | ];
|
42 |
|
43 | const TOKEN_TO_TEXT = {};
|
44 | TOKEN_TO_TEXT[SyntaxKind.OpenBraceToken] = "{";
|
45 | TOKEN_TO_TEXT[SyntaxKind.CloseBraceToken] = "}";
|
46 | TOKEN_TO_TEXT[SyntaxKind.OpenParenToken] = "(";
|
47 | TOKEN_TO_TEXT[SyntaxKind.CloseParenToken] = ")";
|
48 | TOKEN_TO_TEXT[SyntaxKind.OpenBracketToken] = "[";
|
49 | TOKEN_TO_TEXT[SyntaxKind.CloseBracketToken] = "]";
|
50 | TOKEN_TO_TEXT[SyntaxKind.DotToken] = ".";
|
51 | TOKEN_TO_TEXT[SyntaxKind.DotDotDotToken] = "...";
|
52 | TOKEN_TO_TEXT[SyntaxKind.SemicolonToken] = ";";
|
53 | TOKEN_TO_TEXT[SyntaxKind.CommaToken] = ",";
|
54 | TOKEN_TO_TEXT[SyntaxKind.LessThanToken] = "<";
|
55 | TOKEN_TO_TEXT[SyntaxKind.GreaterThanToken] = ">";
|
56 | TOKEN_TO_TEXT[SyntaxKind.LessThanEqualsToken] = "<=";
|
57 | TOKEN_TO_TEXT[SyntaxKind.GreaterThanEqualsToken] = ">=";
|
58 | TOKEN_TO_TEXT[SyntaxKind.EqualsEqualsToken] = "==";
|
59 | TOKEN_TO_TEXT[SyntaxKind.ExclamationEqualsToken] = "!=";
|
60 | TOKEN_TO_TEXT[SyntaxKind.EqualsEqualsEqualsToken] = "===";
|
61 | TOKEN_TO_TEXT[SyntaxKind.InstanceOfKeyword] = "instanceof";
|
62 | TOKEN_TO_TEXT[SyntaxKind.ExclamationEqualsEqualsToken] = "!==";
|
63 | TOKEN_TO_TEXT[SyntaxKind.EqualsGreaterThanToken] = "=>";
|
64 | TOKEN_TO_TEXT[SyntaxKind.PlusToken] = "+";
|
65 | TOKEN_TO_TEXT[SyntaxKind.MinusToken] = "-";
|
66 | TOKEN_TO_TEXT[SyntaxKind.AsteriskToken] = "*";
|
67 | TOKEN_TO_TEXT[SyntaxKind.AsteriskAsteriskToken] = "**";
|
68 | TOKEN_TO_TEXT[SyntaxKind.SlashToken] = "/";
|
69 | TOKEN_TO_TEXT[SyntaxKind.PercentToken] = "%";
|
70 | TOKEN_TO_TEXT[SyntaxKind.PlusPlusToken] = "++";
|
71 | TOKEN_TO_TEXT[SyntaxKind.MinusMinusToken] = "--";
|
72 | TOKEN_TO_TEXT[SyntaxKind.LessThanLessThanToken] = "<<";
|
73 | TOKEN_TO_TEXT[SyntaxKind.LessThanSlashToken] = "</";
|
74 | TOKEN_TO_TEXT[SyntaxKind.GreaterThanGreaterThanToken] = ">>";
|
75 | TOKEN_TO_TEXT[SyntaxKind.GreaterThanGreaterThanGreaterThanToken] = ">>>";
|
76 | TOKEN_TO_TEXT[SyntaxKind.AmpersandToken] = "&";
|
77 | TOKEN_TO_TEXT[SyntaxKind.BarToken] = "|";
|
78 | TOKEN_TO_TEXT[SyntaxKind.CaretToken] = "^";
|
79 | TOKEN_TO_TEXT[SyntaxKind.ExclamationToken] = "!";
|
80 | TOKEN_TO_TEXT[SyntaxKind.TildeToken] = "~";
|
81 | TOKEN_TO_TEXT[SyntaxKind.AmpersandAmpersandToken] = "&&";
|
82 | TOKEN_TO_TEXT[SyntaxKind.BarBarToken] = "||";
|
83 | TOKEN_TO_TEXT[SyntaxKind.QuestionToken] = "?";
|
84 | TOKEN_TO_TEXT[SyntaxKind.ColonToken] = ":";
|
85 | TOKEN_TO_TEXT[SyntaxKind.EqualsToken] = "=";
|
86 | TOKEN_TO_TEXT[SyntaxKind.PlusEqualsToken] = "+=";
|
87 | TOKEN_TO_TEXT[SyntaxKind.MinusEqualsToken] = "-=";
|
88 | TOKEN_TO_TEXT[SyntaxKind.AsteriskEqualsToken] = "*=";
|
89 | TOKEN_TO_TEXT[SyntaxKind.AsteriskAsteriskEqualsToken] = "**=";
|
90 | TOKEN_TO_TEXT[SyntaxKind.SlashEqualsToken] = "/=";
|
91 | TOKEN_TO_TEXT[SyntaxKind.PercentEqualsToken] = "%=";
|
92 | TOKEN_TO_TEXT[SyntaxKind.LessThanLessThanEqualsToken] = "<<=";
|
93 | TOKEN_TO_TEXT[SyntaxKind.GreaterThanGreaterThanEqualsToken] = ">>=";
|
94 | TOKEN_TO_TEXT[SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken] = ">>>=";
|
95 | TOKEN_TO_TEXT[SyntaxKind.AmpersandEqualsToken] = "&=";
|
96 | TOKEN_TO_TEXT[SyntaxKind.BarEqualsToken] = "|=";
|
97 | TOKEN_TO_TEXT[SyntaxKind.CaretEqualsToken] = "^=";
|
98 | TOKEN_TO_TEXT[SyntaxKind.AtToken] = "@";
|
99 | TOKEN_TO_TEXT[SyntaxKind.InKeyword] = "in";
|
100 | TOKEN_TO_TEXT[SyntaxKind.UniqueKeyword] = "unique";
|
101 | TOKEN_TO_TEXT[SyntaxKind.KeyOfKeyword] = "keyof";
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | function findFirstMatchingChild(node, sourceFile, predicate) {
|
111 | const children = node.getChildren(sourceFile);
|
112 | for (let i = 0; i < children.length; i++) {
|
113 | const child = children[i];
|
114 | if (child && predicate(child)) {
|
115 | return child;
|
116 | }
|
117 |
|
118 | const grandChild = findFirstMatchingChild(child, sourceFile, predicate);
|
119 | if (grandChild) {
|
120 | return grandChild;
|
121 | }
|
122 | }
|
123 | return undefined;
|
124 | }
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 | function isLet(node) {
|
132 | |
133 |
|
134 |
|
135 | return ts.isLet(node);
|
136 | }
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 | function isConst(node) {
|
144 | |
145 |
|
146 |
|
147 | return ts.isConst(node);
|
148 | }
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 | module.exports = {
|
156 | |
157 |
|
158 |
|
159 | SyntaxKind,
|
160 | isAssignmentOperator,
|
161 | isLogicalOperator,
|
162 | getTextForTokenKind,
|
163 | isESTreeClassMember,
|
164 | hasModifier,
|
165 | isComma,
|
166 | getBinaryExpressionType,
|
167 | getLocFor,
|
168 | getLoc,
|
169 | isToken,
|
170 | isJSXToken,
|
171 | getDeclarationKind,
|
172 | getTSNodeAccessibility,
|
173 | hasStaticModifierFlag,
|
174 | findNextToken,
|
175 | findFirstMatchingToken,
|
176 | findChildOfKind,
|
177 | findFirstMatchingAncestor,
|
178 | findAncestorOfKind,
|
179 | hasJSXAncestor,
|
180 | unescapeIdentifier,
|
181 | unescapeStringLiteralText,
|
182 | isComputedProperty,
|
183 | isOptional,
|
184 | fixExports,
|
185 | getTokenType,
|
186 | convertToken,
|
187 | convertTokens,
|
188 | getNodeContainer,
|
189 | isWithinTypeAnnotation,
|
190 | isTypeKeyword,
|
191 | isComment,
|
192 | isJSDocComment
|
193 | };
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 | function isAssignmentOperator(operator) {
|
202 | return ASSIGNMENT_OPERATORS.indexOf(operator.kind) > -1;
|
203 | }
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 | function isLogicalOperator(operator) {
|
211 | return LOGICAL_OPERATORS.indexOf(operator.kind) > -1;
|
212 | }
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 | function getTextForTokenKind(kind) {
|
220 | return TOKEN_TO_TEXT[kind];
|
221 | }
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 | function isESTreeClassMember(node) {
|
229 | return node.kind !== SyntaxKind.SemicolonClassElement;
|
230 | }
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 | function hasModifier(modifierKind, node) {
|
239 | return !!node.modifiers && !!node.modifiers.length && node.modifiers.some(modifier => modifier.kind === modifierKind);
|
240 | }
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 | function isComma(token) {
|
248 | return token.kind === SyntaxKind.CommaToken;
|
249 | }
|
250 |
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 | function isComment(node) {
|
257 | return node.kind === SyntaxKind.SingleLineCommentTrivia || node.kind === SyntaxKind.MultiLineCommentTrivia;
|
258 | }
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 | function isJSDocComment(node) {
|
266 | return node.kind === SyntaxKind.JSDocComment;
|
267 | }
|
268 |
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 | function getBinaryExpressionType(operator) {
|
275 | if (isAssignmentOperator(operator)) {
|
276 | return "AssignmentExpression";
|
277 | } else if (isLogicalOperator(operator)) {
|
278 | return "LogicalExpression";
|
279 | }
|
280 | return "BinaryExpression";
|
281 | }
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 | function getLocFor(start, end, ast) {
|
292 | const startLoc = ast.getLineAndCharacterOfPosition(start),
|
293 | endLoc = ast.getLineAndCharacterOfPosition(end);
|
294 |
|
295 | return {
|
296 | start: {
|
297 | line: startLoc.line + 1,
|
298 | column: startLoc.character
|
299 | },
|
300 | end: {
|
301 | line: endLoc.line + 1,
|
302 | column: endLoc.character
|
303 | }
|
304 | };
|
305 | }
|
306 |
|
307 |
|
308 |
|
309 |
|
310 |
|
311 |
|
312 |
|
313 |
|
314 | function getLoc(nodeOrToken, ast) {
|
315 | return getLocFor(nodeOrToken.getStart(), nodeOrToken.end, ast);
|
316 | }
|
317 |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 | function isToken(node) {
|
324 | return node.kind >= SyntaxKind.FirstToken && node.kind <= SyntaxKind.LastToken;
|
325 | }
|
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 | function isJSXToken(node) {
|
333 | return (
|
334 | node.kind >= SyntaxKind.JsxElement &&
|
335 | node.kind <= SyntaxKind.JsxAttribute
|
336 | );
|
337 | }
|
338 |
|
339 |
|
340 |
|
341 |
|
342 |
|
343 |
|
344 | function isTypeKeyword(kind) {
|
345 | switch (kind) {
|
346 | case SyntaxKind.AnyKeyword:
|
347 | case SyntaxKind.BooleanKeyword:
|
348 | case SyntaxKind.NeverKeyword:
|
349 | case SyntaxKind.NumberKeyword:
|
350 | case SyntaxKind.ObjectKeyword:
|
351 | case SyntaxKind.StringKeyword:
|
352 | case SyntaxKind.SymbolKeyword:
|
353 | case SyntaxKind.VoidKeyword:
|
354 | return true;
|
355 | default:
|
356 | return false;
|
357 | }
|
358 | }
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 | function getDeclarationKind(node) {
|
366 | let varDeclarationKind;
|
367 | switch (node.kind) {
|
368 | case SyntaxKind.TypeAliasDeclaration:
|
369 | varDeclarationKind = "type";
|
370 | break;
|
371 | case SyntaxKind.VariableDeclarationList:
|
372 | if (isLet(node)) {
|
373 | varDeclarationKind = "let";
|
374 | } else if (isConst(node)) {
|
375 | varDeclarationKind = "const";
|
376 | } else {
|
377 | varDeclarationKind = "var";
|
378 | }
|
379 | break;
|
380 | default:
|
381 | throw "Unable to determine declaration kind.";
|
382 | }
|
383 | return varDeclarationKind;
|
384 | }
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 | function getTSNodeAccessibility(node) {
|
392 | const modifiers = node.modifiers;
|
393 | if (!modifiers) {
|
394 | return null;
|
395 | }
|
396 | for (let i = 0; i < modifiers.length; i++) {
|
397 | const modifier = modifiers[i];
|
398 | switch (modifier.kind) {
|
399 | case SyntaxKind.PublicKeyword:
|
400 | return "public";
|
401 | case SyntaxKind.ProtectedKeyword:
|
402 | return "protected";
|
403 | case SyntaxKind.PrivateKeyword:
|
404 | return "private";
|
405 | default:
|
406 | continue;
|
407 | }
|
408 | }
|
409 | return null;
|
410 | }
|
411 |
|
412 |
|
413 |
|
414 |
|
415 |
|
416 |
|
417 |
|
418 | function hasStaticModifierFlag(node) {
|
419 | |
420 |
|
421 |
|
422 | return Boolean(ts.getModifierFlags(node) & ts.ModifierFlags.Static);
|
423 | }
|
424 |
|
425 |
|
426 |
|
427 |
|
428 |
|
429 |
|
430 |
|
431 | function findNextToken(previousToken, parent) {
|
432 | |
433 |
|
434 |
|
435 | return ts.findNextToken(previousToken, parent);
|
436 | }
|
437 |
|
438 |
|
439 |
|
440 |
|
441 |
|
442 |
|
443 |
|
444 |
|
445 | function findFirstMatchingToken(previousToken, parent, predicate) {
|
446 | while (previousToken) {
|
447 | if (predicate(previousToken)) {
|
448 | return previousToken;
|
449 | }
|
450 | previousToken = findNextToken(previousToken, parent);
|
451 | }
|
452 | return undefined;
|
453 | }
|
454 |
|
455 |
|
456 |
|
457 |
|
458 |
|
459 |
|
460 |
|
461 |
|
462 | function findChildOfKind(node, kind, sourceFile) {
|
463 | return findFirstMatchingChild(node, sourceFile, child => child.kind === kind);
|
464 | }
|
465 |
|
466 |
|
467 |
|
468 |
|
469 |
|
470 |
|
471 |
|
472 | function findFirstMatchingAncestor(node, predicate) {
|
473 | while (node) {
|
474 | if (predicate(node)) {
|
475 | return node;
|
476 | }
|
477 | node = node.parent;
|
478 | }
|
479 | return undefined;
|
480 | }
|
481 |
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 | function findAncestorOfKind(node, kind) {
|
489 | return findFirstMatchingAncestor(node, parent => parent.kind === kind);
|
490 | }
|
491 |
|
492 |
|
493 |
|
494 |
|
495 |
|
496 |
|
497 |
|
498 | function hasJSXAncestor(node) {
|
499 | return !!findFirstMatchingAncestor(node, isJSXToken);
|
500 | }
|
501 |
|
502 |
|
503 |
|
504 |
|
505 |
|
506 |
|
507 | function unescapeIdentifier(identifier) {
|
508 | return ts.unescapeIdentifier(identifier);
|
509 | }
|
510 |
|
511 |
|
512 |
|
513 |
|
514 |
|
515 |
|
516 | function unescapeStringLiteralText(text) {
|
517 | return unescape(text);
|
518 | }
|
519 |
|
520 |
|
521 |
|
522 |
|
523 |
|
524 |
|
525 | function isComputedProperty(node) {
|
526 | return node.kind === SyntaxKind.ComputedPropertyName;
|
527 | }
|
528 |
|
529 |
|
530 |
|
531 |
|
532 |
|
533 |
|
534 | function isOptional(node) {
|
535 | return (node.questionToken)
|
536 | ? (node.questionToken.kind === SyntaxKind.QuestionToken) : false;
|
537 | }
|
538 |
|
539 |
|
540 |
|
541 |
|
542 |
|
543 |
|
544 |
|
545 | function isWithinTypeAnnotation(node) {
|
546 | return node.parent.type === node || (node.parent.types && node.parent.types.indexOf(node) > -1);
|
547 | }
|
548 |
|
549 |
|
550 |
|
551 |
|
552 |
|
553 |
|
554 |
|
555 |
|
556 | function fixExports(node, result, ast) {
|
557 |
|
558 | if (node.modifiers && node.modifiers[0].kind === SyntaxKind.ExportKeyword) {
|
559 | const exportKeyword = node.modifiers[0],
|
560 | nextModifier = node.modifiers[1],
|
561 | lastModifier = node.modifiers[node.modifiers.length - 1],
|
562 | declarationIsDefault = nextModifier && (nextModifier.kind === SyntaxKind.DefaultKeyword),
|
563 | varToken = findNextToken(lastModifier, ast);
|
564 |
|
565 | result.range[0] = varToken.getStart();
|
566 | result.loc = getLocFor(result.range[0], result.range[1], ast);
|
567 |
|
568 | const declarationType = declarationIsDefault ? "ExportDefaultDeclaration" : "ExportNamedDeclaration";
|
569 |
|
570 | const newResult = {
|
571 | type: declarationType,
|
572 | declaration: result,
|
573 | range: [exportKeyword.getStart(), result.range[1]],
|
574 | loc: getLocFor(exportKeyword.getStart(), result.range[1], ast)
|
575 | };
|
576 |
|
577 | if (!declarationIsDefault) {
|
578 | newResult.specifiers = [];
|
579 | newResult.source = null;
|
580 | }
|
581 |
|
582 | return newResult;
|
583 |
|
584 | }
|
585 |
|
586 | return result;
|
587 | }
|
588 |
|
589 |
|
590 |
|
591 |
|
592 |
|
593 |
|
594 | function getTokenType(token) {
|
595 |
|
596 | if (token.originalKeywordKind) {
|
597 |
|
598 | switch (token.originalKeywordKind) {
|
599 | case SyntaxKind.NullKeyword:
|
600 | return "Null";
|
601 |
|
602 | case SyntaxKind.GetKeyword:
|
603 | case SyntaxKind.SetKeyword:
|
604 | case SyntaxKind.TypeKeyword:
|
605 | case SyntaxKind.ModuleKeyword:
|
606 | return "Identifier";
|
607 |
|
608 | default:
|
609 | return "Keyword";
|
610 | }
|
611 | }
|
612 |
|
613 | if (token.kind >= SyntaxKind.FirstKeyword && token.kind <= SyntaxKind.LastFutureReservedWord) {
|
614 | if (token.kind === SyntaxKind.FalseKeyword || token.kind === SyntaxKind.TrueKeyword) {
|
615 | return "Boolean";
|
616 | }
|
617 |
|
618 | return "Keyword";
|
619 | }
|
620 |
|
621 | if (token.kind >= SyntaxKind.FirstPunctuation && token.kind <= SyntaxKind.LastBinaryOperator) {
|
622 | return "Punctuator";
|
623 | }
|
624 |
|
625 | if (token.kind >= SyntaxKind.NoSubstitutionTemplateLiteral && token.kind <= SyntaxKind.TemplateTail) {
|
626 | return "Template";
|
627 | }
|
628 |
|
629 | switch (token.kind) {
|
630 | case SyntaxKind.NumericLiteral:
|
631 | return "Numeric";
|
632 |
|
633 | case SyntaxKind.JsxText:
|
634 | return "JSXText";
|
635 |
|
636 | case SyntaxKind.StringLiteral:
|
637 |
|
638 |
|
639 |
|
640 | if (token.parent && (token.parent.kind === SyntaxKind.JsxAttribute || token.parent.kind === SyntaxKind.JsxElement)) {
|
641 | return "JSXText";
|
642 | }
|
643 |
|
644 | return "String";
|
645 |
|
646 | case SyntaxKind.RegularExpressionLiteral:
|
647 | return "RegularExpression";
|
648 |
|
649 | case SyntaxKind.Identifier:
|
650 | case SyntaxKind.ConstructorKeyword:
|
651 | case SyntaxKind.GetKeyword:
|
652 | case SyntaxKind.SetKeyword:
|
653 |
|
654 |
|
655 | default:
|
656 | }
|
657 |
|
658 |
|
659 | if (token.parent) {
|
660 | if (token.kind === SyntaxKind.Identifier && token.parent.kind === SyntaxKind.PropertyAccessExpression && hasJSXAncestor(token)) {
|
661 | return "JSXIdentifier";
|
662 | }
|
663 |
|
664 | if (isJSXToken(token.parent)) {
|
665 | if (token.kind === SyntaxKind.PropertyAccessExpression) {
|
666 | return "JSXMemberExpression";
|
667 | }
|
668 |
|
669 | if (token.kind === SyntaxKind.Identifier) {
|
670 | return "JSXIdentifier";
|
671 | }
|
672 | }
|
673 | }
|
674 |
|
675 | return "Identifier";
|
676 | }
|
677 |
|
678 |
|
679 |
|
680 |
|
681 |
|
682 |
|
683 |
|
684 | function convertToken(token, ast) {
|
685 | const start = (token.kind === SyntaxKind.JsxText) ? token.getFullStart() : token.getStart(),
|
686 | end = token.getEnd(),
|
687 | value = ast.text.slice(start, end),
|
688 | newToken = {
|
689 | type: getTokenType(token),
|
690 | value,
|
691 | range: [start, end],
|
692 | loc: getLocFor(start, end, ast)
|
693 | };
|
694 |
|
695 | if (newToken.type === "RegularExpression") {
|
696 | newToken.regex = {
|
697 | pattern: value.slice(1, value.lastIndexOf("/")),
|
698 | flags: value.slice(value.lastIndexOf("/") + 1)
|
699 | };
|
700 | }
|
701 |
|
702 | return newToken;
|
703 | }
|
704 |
|
705 |
|
706 |
|
707 |
|
708 |
|
709 |
|
710 | function convertTokens(ast) {
|
711 | const result = [];
|
712 | |
713 |
|
714 |
|
715 |
|
716 | function walk(node) {
|
717 |
|
718 |
|
719 | if (isComment(node) || isJSDocComment(node)) {
|
720 | return;
|
721 | }
|
722 |
|
723 | if (isToken(node) && node.kind !== SyntaxKind.EndOfFileToken) {
|
724 | const converted = convertToken(node, ast);
|
725 |
|
726 | if (converted) {
|
727 | result.push(converted);
|
728 | }
|
729 | } else {
|
730 | node.getChildren().forEach(walk);
|
731 | }
|
732 | }
|
733 | walk(ast);
|
734 | return result;
|
735 | }
|
736 |
|
737 |
|
738 |
|
739 |
|
740 |
|
741 |
|
742 |
|
743 |
|
744 |
|
745 | function getNodeContainer(ast, start, end) {
|
746 | let container = null;
|
747 |
|
748 | |
749 |
|
750 |
|
751 |
|
752 | function walk(node) {
|
753 | const nodeStart = node.pos;
|
754 | const nodeEnd = node.end;
|
755 |
|
756 | if (start >= nodeStart && end <= nodeEnd) {
|
757 | if (isToken(node)) {
|
758 | container = node;
|
759 | } else {
|
760 | node.getChildren().forEach(walk);
|
761 | }
|
762 | }
|
763 | }
|
764 | walk(ast);
|
765 |
|
766 | return container;
|
767 | }
|