1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
|
4 | const eslint_visitor_keys_1 = require("eslint-visitor-keys");
|
5 | const scope_manager_1 = require("./scope/scope-manager");
|
6 | const typescript_estree_1 = require("@typescript-eslint/typescript-estree");
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | function overrideDefine(define) {
|
13 | return function (node, definition) {
|
14 | define.call(this, node, definition);
|
15 |
|
16 | const variable = 'name' in node &&
|
17 | typeof node.name === 'string' &&
|
18 | this.set.get(node.name);
|
19 | if (variable) {
|
20 | variable.eslintUsed = true;
|
21 | }
|
22 | };
|
23 | }
|
24 | class PatternVisitor extends experimental_utils_1.TSESLintScope.PatternVisitor {
|
25 | constructor(options, rootPattern, callback) {
|
26 | super(options, rootPattern, callback);
|
27 | }
|
28 | Identifier(node) {
|
29 | super.Identifier(node);
|
30 | if (node.decorators) {
|
31 | this.rightHandNodes.push(...node.decorators);
|
32 | }
|
33 | if (node.typeAnnotation) {
|
34 | this.rightHandNodes.push(node.typeAnnotation);
|
35 | }
|
36 | }
|
37 | ArrayPattern(node) {
|
38 | node.elements.forEach(this.visit, this);
|
39 | if (node.decorators) {
|
40 | this.rightHandNodes.push(...node.decorators);
|
41 | }
|
42 | if (node.typeAnnotation) {
|
43 | this.rightHandNodes.push(node.typeAnnotation);
|
44 | }
|
45 | }
|
46 | ObjectPattern(node) {
|
47 | node.properties.forEach(this.visit, this);
|
48 | if (node.decorators) {
|
49 | this.rightHandNodes.push(...node.decorators);
|
50 | }
|
51 | if (node.typeAnnotation) {
|
52 | this.rightHandNodes.push(node.typeAnnotation);
|
53 | }
|
54 | }
|
55 | RestElement(node) {
|
56 | super.RestElement(node);
|
57 | if (node.decorators) {
|
58 | this.rightHandNodes.push(...node.decorators);
|
59 | }
|
60 | if (node.typeAnnotation) {
|
61 | this.rightHandNodes.push(node.typeAnnotation);
|
62 | }
|
63 | }
|
64 | TSParameterProperty(node) {
|
65 | this.visit(node.parameter);
|
66 | if (node.decorators) {
|
67 | this.rightHandNodes.push(...node.decorators);
|
68 | }
|
69 | }
|
70 | }
|
71 | class Referencer extends experimental_utils_1.TSESLintScope.Referencer {
|
72 | constructor(options, scopeManager) {
|
73 | super(options, scopeManager);
|
74 | this.typeMode = false;
|
75 | }
|
76 | |
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | visitPattern(node, options, callback) {
|
83 | if (!node) {
|
84 | return;
|
85 | }
|
86 | if (typeof options === 'function') {
|
87 | callback = options;
|
88 | options = { processRightHandNodes: false };
|
89 | }
|
90 | const visitor = new PatternVisitor(this.options, node, callback);
|
91 | visitor.visit(node);
|
92 | if (options.processRightHandNodes) {
|
93 | visitor.rightHandNodes.forEach(this.visit, this);
|
94 | }
|
95 | }
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 | visitFunction(node) {
|
102 | const { type, id, typeParameters, params, returnType, body } = node;
|
103 | const scopeManager = this.scopeManager;
|
104 | const upperScope = this.currentScope();
|
105 |
|
106 | if (type === experimental_utils_1.AST_NODE_TYPES.FunctionDeclaration && id) {
|
107 | upperScope.__define(id, new experimental_utils_1.TSESLintScope.Definition('FunctionName', id, node, null, null, null));
|
108 |
|
109 | const { defs, identifiers } = upperScope.set.get(id.name);
|
110 | for (let i = 0; i < defs.length; ++i) {
|
111 | const def = defs[i];
|
112 | if (def.type === 'FunctionName' &&
|
113 | def.node.type === experimental_utils_1.AST_NODE_TYPES.TSDeclareFunction) {
|
114 | defs.splice(i, 1);
|
115 | identifiers.splice(i, 1);
|
116 | break;
|
117 | }
|
118 | }
|
119 | }
|
120 | else if (type === experimental_utils_1.AST_NODE_TYPES.FunctionExpression && id) {
|
121 | scopeManager.__nestFunctionExpressionNameScope(node);
|
122 | }
|
123 |
|
124 | scopeManager.__nestFunctionScope(node, this.isInnerMethodDefinition);
|
125 | const innerScope = this.currentScope();
|
126 |
|
127 | this.visit(typeParameters);
|
128 |
|
129 | for (let i = 0; i < params.length; ++i) {
|
130 | this.visitPattern(params[i], { processRightHandNodes: true }, (pattern, info) => {
|
131 | if (pattern.type !== experimental_utils_1.AST_NODE_TYPES.Identifier ||
|
132 | pattern.name !== 'this') {
|
133 | innerScope.__define(pattern, new experimental_utils_1.TSESLintScope.ParameterDefinition(pattern, node, i, info.rest));
|
134 | this.referencingDefaultValue(pattern, info.assignments, null, true);
|
135 | }
|
136 | });
|
137 | }
|
138 |
|
139 | this.visit(returnType);
|
140 |
|
141 | if (body && body.type === experimental_utils_1.AST_NODE_TYPES.BlockStatement) {
|
142 | this.visitChildren(body);
|
143 | }
|
144 | else {
|
145 | this.visit(body);
|
146 | }
|
147 |
|
148 | this.close(node);
|
149 | }
|
150 | |
151 |
|
152 |
|
153 |
|
154 |
|
155 | visitClass(node) {
|
156 | this.visitDecorators(node.decorators);
|
157 | const upperTypeMode = this.typeMode;
|
158 | this.typeMode = true;
|
159 | if (node.superTypeParameters) {
|
160 | this.visit(node.superTypeParameters);
|
161 | }
|
162 | if (node.implements) {
|
163 | node.implements.forEach(this.visit, this);
|
164 | }
|
165 | this.typeMode = upperTypeMode;
|
166 | super.visitClass(node);
|
167 | }
|
168 | |
169 |
|
170 |
|
171 |
|
172 | visitTypeParameters(node) {
|
173 | if (node.typeParameters) {
|
174 | const upperTypeMode = this.typeMode;
|
175 | this.typeMode = true;
|
176 | this.visit(node.typeParameters);
|
177 | this.typeMode = upperTypeMode;
|
178 | }
|
179 | }
|
180 | |
181 |
|
182 |
|
183 | JSXOpeningElement(node) {
|
184 | this.visit(node.name);
|
185 | this.visitTypeParameters(node);
|
186 | node.attributes.forEach(this.visit, this);
|
187 | }
|
188 | |
189 |
|
190 |
|
191 |
|
192 |
|
193 | Identifier(node) {
|
194 | this.visitDecorators(node.decorators);
|
195 | if (!this.typeMode) {
|
196 | super.Identifier(node);
|
197 | }
|
198 | this.visit(node.typeAnnotation);
|
199 | }
|
200 | |
201 |
|
202 |
|
203 |
|
204 |
|
205 | MethodDefinition(node) {
|
206 | this.visitDecorators(node.decorators);
|
207 | super.MethodDefinition(node);
|
208 | }
|
209 | |
210 |
|
211 |
|
212 |
|
213 | ClassProperty(node) {
|
214 | const upperTypeMode = this.typeMode;
|
215 | const { computed, decorators, key, typeAnnotation, value } = node;
|
216 | this.typeMode = false;
|
217 | this.visitDecorators(decorators);
|
218 | if (computed) {
|
219 | this.visit(key);
|
220 | }
|
221 | this.typeMode = true;
|
222 | this.visit(typeAnnotation);
|
223 | this.typeMode = false;
|
224 | this.visit(value);
|
225 | this.typeMode = upperTypeMode;
|
226 | }
|
227 | |
228 |
|
229 |
|
230 |
|
231 | NewExpression(node) {
|
232 | this.visitTypeParameters(node);
|
233 | this.visit(node.callee);
|
234 | node.arguments.forEach(this.visit, this);
|
235 | }
|
236 | |
237 |
|
238 |
|
239 |
|
240 |
|
241 | CallExpression(node) {
|
242 | this.visitTypeParameters(node);
|
243 | this.visit(node.callee);
|
244 | node.arguments.forEach(this.visit, this);
|
245 | }
|
246 | |
247 |
|
248 |
|
249 |
|
250 | OptionalMemberExpression(node) {
|
251 | this.visit(node.object);
|
252 | if (node.computed) {
|
253 | this.visit(node.property);
|
254 | }
|
255 | }
|
256 | |
257 |
|
258 |
|
259 |
|
260 | OptionalCallExpression(node) {
|
261 | this.visitTypeParameters(node);
|
262 | this.visit(node.callee);
|
263 | node.arguments.forEach(this.visit, this);
|
264 | }
|
265 | |
266 |
|
267 |
|
268 |
|
269 |
|
270 | TSDeclareFunction(node) {
|
271 | var _a, _b;
|
272 | const scopeManager = this.scopeManager;
|
273 | const upperScope = this.currentScope();
|
274 | const { id, typeParameters, params, returnType } = node;
|
275 |
|
276 | if (id) {
|
277 | const variable = upperScope.set.get(id.name);
|
278 | const defs = (_a = variable) === null || _a === void 0 ? void 0 : _a.defs;
|
279 | const existed = (_b = defs) === null || _b === void 0 ? void 0 : _b.some((d) => d.type === 'FunctionName');
|
280 | if (!existed) {
|
281 | upperScope.__define(id, new experimental_utils_1.TSESLintScope.Definition('FunctionName', id, node, null, null, null));
|
282 | }
|
283 | }
|
284 |
|
285 | scopeManager.__nestEmptyFunctionScope(node);
|
286 | const innerScope = this.currentScope();
|
287 |
|
288 | this.visit(typeParameters);
|
289 |
|
290 | for (let i = 0; i < params.length; ++i) {
|
291 | this.visitPattern(params[i], { processRightHandNodes: true }, (pattern, info) => {
|
292 | innerScope.__define(pattern, new experimental_utils_1.TSESLintScope.ParameterDefinition(pattern, node, i, info.rest));
|
293 |
|
294 | const variable = innerScope.set.get(pattern.name);
|
295 | if (variable) {
|
296 | variable.eslintUsed = true;
|
297 | }
|
298 | this.referencingDefaultValue(pattern, info.assignments, null, true);
|
299 | });
|
300 | }
|
301 |
|
302 | this.visit(returnType);
|
303 |
|
304 | this.close(node);
|
305 | }
|
306 | |
307 |
|
308 |
|
309 |
|
310 | TSEmptyBodyFunctionExpression(node) {
|
311 | const upperTypeMode = this.typeMode;
|
312 | const { typeParameters, params, returnType } = node;
|
313 | this.typeMode = true;
|
314 | this.visit(typeParameters);
|
315 | params.forEach(this.visit, this);
|
316 | this.visit(returnType);
|
317 | this.typeMode = upperTypeMode;
|
318 | }
|
319 | |
320 |
|
321 |
|
322 |
|
323 |
|
324 | TSInterfaceDeclaration(node) {
|
325 | this.visitTypeNodes(node);
|
326 | }
|
327 | |
328 |
|
329 |
|
330 |
|
331 |
|
332 | TSClassImplements(node) {
|
333 | this.visitTypeNodes(node);
|
334 | }
|
335 | |
336 |
|
337 |
|
338 |
|
339 |
|
340 | TSIndexSignature(node) {
|
341 | this.visitTypeNodes(node);
|
342 | }
|
343 | |
344 |
|
345 |
|
346 |
|
347 | TSTypeAssertion(node) {
|
348 | if (this.typeMode) {
|
349 | this.visit(node.typeAnnotation);
|
350 | }
|
351 | else {
|
352 | this.typeMode = true;
|
353 | this.visit(node.typeAnnotation);
|
354 | this.typeMode = false;
|
355 | }
|
356 | this.visit(node.expression);
|
357 | }
|
358 | |
359 |
|
360 |
|
361 |
|
362 | TSAsExpression(node) {
|
363 | this.visit(node.expression);
|
364 | if (this.typeMode) {
|
365 | this.visit(node.typeAnnotation);
|
366 | }
|
367 | else {
|
368 | this.typeMode = true;
|
369 | this.visit(node.typeAnnotation);
|
370 | this.typeMode = false;
|
371 | }
|
372 | }
|
373 | |
374 |
|
375 |
|
376 |
|
377 | TSTypeAnnotation(node) {
|
378 | this.visitTypeNodes(node);
|
379 | }
|
380 | |
381 |
|
382 |
|
383 |
|
384 | TSTypeParameterDeclaration(node) {
|
385 | this.visitTypeNodes(node);
|
386 | }
|
387 | |
388 |
|
389 |
|
390 |
|
391 | TSTypeQuery(node) {
|
392 | if (this.typeMode) {
|
393 | this.typeMode = false;
|
394 | this.visitChildren(node);
|
395 | this.typeMode = true;
|
396 | }
|
397 | else {
|
398 | this.visitChildren(node);
|
399 | }
|
400 | }
|
401 | |
402 |
|
403 |
|
404 | TSTypeParameter(node) {
|
405 | this.visitTypeNodes(node);
|
406 | }
|
407 | |
408 |
|
409 |
|
410 | TSInferType(node) {
|
411 | this.visitTypeNodes(node);
|
412 | }
|
413 | |
414 |
|
415 |
|
416 | TSTypeReference(node) {
|
417 | this.visitTypeNodes(node);
|
418 | }
|
419 | |
420 |
|
421 |
|
422 | TSTypeLiteral(node) {
|
423 | this.visitTypeNodes(node);
|
424 | }
|
425 | |
426 |
|
427 |
|
428 | TSLiteralType(node) {
|
429 | this.visitTypeNodes(node);
|
430 | }
|
431 | |
432 |
|
433 |
|
434 | TSIntersectionType(node) {
|
435 | this.visitTypeNodes(node);
|
436 | }
|
437 | |
438 |
|
439 |
|
440 | TSConditionalType(node) {
|
441 | this.visitTypeNodes(node);
|
442 | }
|
443 | |
444 |
|
445 |
|
446 | TSIndexedAccessType(node) {
|
447 | this.visitTypeNodes(node);
|
448 | }
|
449 | |
450 |
|
451 |
|
452 | TSMappedType(node) {
|
453 | this.visitTypeNodes(node);
|
454 | }
|
455 | |
456 |
|
457 |
|
458 | TSOptionalType(node) {
|
459 | this.visitTypeNodes(node);
|
460 | }
|
461 | |
462 |
|
463 |
|
464 | TSParenthesizedType(node) {
|
465 | this.visitTypeNodes(node);
|
466 | }
|
467 | |
468 |
|
469 |
|
470 | TSRestType(node) {
|
471 | this.visitTypeNodes(node);
|
472 | }
|
473 | |
474 |
|
475 |
|
476 | TSTupleType(node) {
|
477 | this.visitTypeNodes(node);
|
478 | }
|
479 | |
480 |
|
481 |
|
482 |
|
483 | TSQualifiedName(node) {
|
484 | this.visit(node.left);
|
485 | }
|
486 | |
487 |
|
488 |
|
489 |
|
490 | TSPropertySignature(node) {
|
491 | const upperTypeMode = this.typeMode;
|
492 | const { computed, key, typeAnnotation, initializer } = node;
|
493 | if (computed) {
|
494 | this.typeMode = false;
|
495 | this.visit(key);
|
496 | this.typeMode = true;
|
497 | }
|
498 | else {
|
499 | this.typeMode = true;
|
500 | this.visit(key);
|
501 | }
|
502 | this.visit(typeAnnotation);
|
503 | this.visit(initializer);
|
504 | this.typeMode = upperTypeMode;
|
505 | }
|
506 | |
507 |
|
508 |
|
509 |
|
510 | TSMethodSignature(node) {
|
511 | const upperTypeMode = this.typeMode;
|
512 | const { computed, key, typeParameters, params, returnType } = node;
|
513 | if (computed) {
|
514 | this.typeMode = false;
|
515 | this.visit(key);
|
516 | this.typeMode = true;
|
517 | }
|
518 | else {
|
519 | this.typeMode = true;
|
520 | this.visit(key);
|
521 | }
|
522 | this.visit(typeParameters);
|
523 | params.forEach(this.visit, this);
|
524 | this.visit(returnType);
|
525 | this.typeMode = upperTypeMode;
|
526 | }
|
527 | |
528 |
|
529 |
|
530 |
|
531 |
|
532 |
|
533 |
|
534 |
|
535 |
|
536 |
|
537 |
|
538 |
|
539 |
|
540 |
|
541 |
|
542 |
|
543 |
|
544 | TSEnumDeclaration(node) {
|
545 | const { id, members } = node;
|
546 | const scopeManager = this.scopeManager;
|
547 | const scope = this.currentScope();
|
548 | if (id) {
|
549 | scope.__define(id, new experimental_utils_1.TSESLintScope.Definition('EnumName', id, node));
|
550 | }
|
551 | scopeManager.__nestEnumScope(node);
|
552 | for (const member of members) {
|
553 | this.visit(member);
|
554 | }
|
555 | this.close(node);
|
556 | }
|
557 | |
558 |
|
559 |
|
560 |
|
561 |
|
562 |
|
563 | TSEnumMember(node) {
|
564 | const { id, initializer } = node;
|
565 | const scope = this.currentScope();
|
566 | scope.__define(id, new experimental_utils_1.TSESLintScope.Definition('EnumMemberName', id, node));
|
567 | if (initializer) {
|
568 | scope.__referencing(id, experimental_utils_1.TSESLintScope.Reference.WRITE, initializer, null, false, true);
|
569 | this.visit(initializer);
|
570 | }
|
571 | }
|
572 | |
573 |
|
574 |
|
575 |
|
576 | TSModuleDeclaration(node) {
|
577 | const scope = this.currentScope();
|
578 | const { id, body } = node;
|
579 | if (node.global) {
|
580 | this.visitGlobalAugmentation(node);
|
581 | return;
|
582 | }
|
583 | if (id && id.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
|
584 | scope.__define(id, new experimental_utils_1.TSESLintScope.Definition('NamespaceName', id, node, null, null, null));
|
585 | }
|
586 | this.visit(body);
|
587 | }
|
588 | TSTypeAliasDeclaration(node) {
|
589 | this.typeMode = true;
|
590 | this.visitChildren(node);
|
591 | this.typeMode = false;
|
592 | }
|
593 | |
594 |
|
595 |
|
596 |
|
597 | TSModuleBlock(node) {
|
598 | this.scopeManager.__nestBlockScope(node);
|
599 | this.visitChildren(node);
|
600 | this.close(node);
|
601 | }
|
602 | TSAbstractClassProperty(node) {
|
603 | this.ClassProperty(node);
|
604 | }
|
605 | TSAbstractMethodDefinition(node) {
|
606 | this.MethodDefinition(node);
|
607 | }
|
608 | |
609 |
|
610 |
|
611 |
|
612 | TSImportEqualsDeclaration(node) {
|
613 | const { id, moduleReference } = node;
|
614 | if (id && id.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
|
615 | this.currentScope().__define(id, new experimental_utils_1.TSESLintScope.Definition('ImportBinding', id, node, null, null, null));
|
616 | }
|
617 | this.visit(moduleReference);
|
618 | }
|
619 | |
620 |
|
621 |
|
622 |
|
623 |
|
624 |
|
625 | visitGlobalAugmentation(node) {
|
626 | const scopeManager = this.scopeManager;
|
627 | const currentScope = this.currentScope();
|
628 | const globalScope = scopeManager.globalScope;
|
629 | const originalDefine = globalScope.__define;
|
630 | globalScope.__define = overrideDefine(originalDefine);
|
631 | scopeManager.__currentScope = globalScope;
|
632 |
|
633 | if (node.body && node.body.type === experimental_utils_1.AST_NODE_TYPES.TSModuleBlock) {
|
634 | node.body.body.forEach(this.visit, this);
|
635 | }
|
636 | scopeManager.__currentScope = currentScope;
|
637 | globalScope.__define = originalDefine;
|
638 | }
|
639 | |
640 |
|
641 |
|
642 |
|
643 | visitDecorators(decorators) {
|
644 | if (decorators) {
|
645 | decorators.forEach(this.visit, this);
|
646 | }
|
647 | }
|
648 | |
649 |
|
650 |
|
651 |
|
652 | visitTypeNodes(node) {
|
653 | if (this.typeMode) {
|
654 | this.visitChildren(node);
|
655 | }
|
656 | else {
|
657 | this.typeMode = true;
|
658 | this.visitChildren(node);
|
659 | this.typeMode = false;
|
660 | }
|
661 | }
|
662 | }
|
663 | function analyzeScope(ast, parserOptions) {
|
664 | var _a;
|
665 | const options = {
|
666 | ignoreEval: true,
|
667 | optimistic: false,
|
668 | directive: false,
|
669 | nodejsScope: parserOptions.sourceType === 'script' &&
|
670 | (parserOptions.ecmaFeatures &&
|
671 | parserOptions.ecmaFeatures.globalReturn) === true,
|
672 | impliedStrict: false,
|
673 | sourceType: parserOptions.sourceType,
|
674 | ecmaVersion: (_a = parserOptions.ecmaVersion, (_a !== null && _a !== void 0 ? _a : 2018)),
|
675 | childVisitorKeys: typescript_estree_1.visitorKeys,
|
676 | fallback: eslint_visitor_keys_1.getKeys,
|
677 | };
|
678 | const scopeManager = new scope_manager_1.ScopeManager(options);
|
679 | const referencer = new Referencer(options, scopeManager);
|
680 | referencer.visit(ast);
|
681 | return scopeManager;
|
682 | }
|
683 | exports.analyzeScope = analyzeScope;
|
684 |
|
\ | No newline at end of file |