Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a77c94e

Browse files
committed
feat: treat type imports as type-only
1 parent 007fc21 commit a77c94e

27 files changed

+313
-196
lines changed

packages/scope-manager/src/ScopeManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class ScopeManager {
124124
}
125125
}
126126
} else {
127-
for (let i = 0, iz = scopes.length; i < iz; ++i) {
127+
for (let i = 0; i < scopes.length; ++i) {
128128
const scope = scopes[i];
129129

130130
if (predicate(scope)) {

packages/scope-manager/src/Variable.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import { TSESTree } from '@typescript-eslint/experimental-utils';
2-
import {
3-
Definition,
4-
TypeDefinitionTypes,
5-
ValueDefinitionTypes,
6-
} from './definition';
2+
import { Definition } from './definition';
73
import { createIdGenerator } from './ID';
84
import { Reference } from './referencer/Reference';
95
import { Scope } from './scope';
@@ -65,7 +61,7 @@ class Variable {
6561
return true;
6662
}
6763

68-
return this.defs.some(def => TypeDefinitionTypes.has(def.type));
64+
return this.defs.some(def => def.isTypeDefinition);
6965
}
7066

7167
/**
@@ -77,7 +73,7 @@ class Variable {
7773
return true;
7874
}
7975

80-
return this.defs.some(def => ValueDefinitionTypes.has(def.type));
76+
return this.defs.some(def => def.isVariableDefinition);
8177
}
8278
}
8379

packages/scope-manager/src/analyze.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ interface Options {
4343
const DEFAULT_OPTIONS: Options = {
4444
gloablReturn: false,
4545
impliedStrict: false,
46-
sourceType: 'script',
46+
sourceType: 'module',
4747
ecmaVersion: 2018,
4848
childVisitorKeys: visitorKeys,
4949
fallback: 'iteration',

packages/scope-manager/src/definition/CatchClauseDefinition.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ class CatchClauseDefinition extends DefinitionBase<
1010
constructor(name: TSESTree.BindingName, node: CatchClauseDefinition['node']) {
1111
super(DefinitionType.CatchClause, name, node, null);
1212
}
13+
14+
public readonly isTypeDefinition = false;
15+
public readonly isVariableDefinition = true;
1316
}
1417

1518
export { CatchClauseDefinition };

packages/scope-manager/src/definition/ClassNameDefinition.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ class ClassNameDefinition extends DefinitionBase<
1010
constructor(name: TSESTree.Identifier, node: ClassNameDefinition['node']) {
1111
super(DefinitionType.ClassName, name, node, null);
1212
}
13+
14+
public readonly isTypeDefinition = true;
15+
public readonly isVariableDefinition = true;
1316
}
1417

1518
export { ClassNameDefinition };

packages/scope-manager/src/definition/DefinitionBase.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createIdGenerator } from '../ID';
44

55
const generator = createIdGenerator();
66

7-
class DefinitionBase<
7+
abstract class DefinitionBase<
88
TType extends DefinitionType,
99
TNode extends TSESTree.Node,
1010
TParent extends TSESTree.Node | null
@@ -49,6 +49,16 @@ class DefinitionBase<
4949
this.node = node;
5050
this.parent = parent;
5151
}
52+
53+
/**
54+
* `true` if the variable is valid in a type context, false otherwise
55+
*/
56+
public abstract readonly isTypeDefinition: boolean;
57+
58+
/**
59+
* `true` if the variable is valid in a value context, false otherwise
60+
*/
61+
public abstract readonly isVariableDefinition: boolean;
5262
}
5363

5464
export { DefinitionBase };

packages/scope-manager/src/definition/DefinitionType.ts

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,4 @@ enum DefinitionType {
1010
Variable = 'Variable',
1111
}
1212

13-
/**
14-
* The DefinitionTypes that are valid in a type context
15-
*/
16-
const TypeDefinitionTypes = new Set([
17-
DefinitionType.ClassName,
18-
DefinitionType.Type,
19-
]);
20-
21-
/**
22-
* The DefinitionTypes that are valid in a value context
23-
*/
24-
const ValueDefinitionTypes = new Set([
25-
DefinitionType.CatchClause,
26-
DefinitionType.ClassName,
27-
DefinitionType.FunctionName,
28-
DefinitionType.ImplicitGlobalVariable,
29-
DefinitionType.ImportBinding,
30-
DefinitionType.Parameter,
31-
DefinitionType.Variable,
32-
]);
33-
34-
export { DefinitionType, TypeDefinitionTypes, ValueDefinitionTypes };
13+
export { DefinitionType };

packages/scope-manager/src/definition/FunctionNameDefinition.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ class FunctionNameDefinition extends DefinitionBase<
1010
constructor(name: TSESTree.Identifier, node: FunctionNameDefinition['node']) {
1111
super(DefinitionType.FunctionName, name, node, null);
1212
}
13+
14+
public readonly isTypeDefinition = false;
15+
public readonly isVariableDefinition = true;
1316
}
1417

1518
export { FunctionNameDefinition };

packages/scope-manager/src/definition/ImplicitGlobalVariableDefinition.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ class ImplicitGlobalVariableDefinition extends DefinitionBase<
1313
) {
1414
super(DefinitionType.ImplicitGlobalVariable, name, node, null);
1515
}
16+
17+
public readonly isTypeDefinition = false;
18+
public readonly isVariableDefinition = true;
1619
}
1720

1821
export { ImplicitGlobalVariableDefinition };

packages/scope-manager/src/definition/ImportBindingDefinition.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ class ImportBindingDefinition extends DefinitionBase<
1515
decl: TSESTree.ImportDeclaration,
1616
) {
1717
super(DefinitionType.ImportBinding, name, node, decl);
18+
this.isVariableDefinition = this.parent.importKind !== 'type';
1819
}
20+
21+
public readonly isTypeDefinition = true;
22+
public readonly isVariableDefinition: boolean;
1923
}
2024

2125
export { ImportBindingDefinition };

packages/scope-manager/src/definition/ParameterDefinition.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class ParameterDefinition extends DefinitionBase<
2121
super(DefinitionType.Parameter, name, node, null);
2222
this.rest = rest;
2323
}
24+
25+
public readonly isTypeDefinition = false;
26+
public readonly isVariableDefinition = true;
2427
}
2528

2629
export { ParameterDefinition };

packages/scope-manager/src/definition/TypeDefinition.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ class TypeDefinition extends DefinitionBase<
1010
constructor(name: TSESTree.Identifier, node: TSESTree.Node) {
1111
super(DefinitionType.Type, name, node, null);
1212
}
13+
14+
public readonly isTypeDefinition = true;
15+
public readonly isVariableDefinition = false;
1316
}
1417

1518
export { TypeDefinition };

packages/scope-manager/src/definition/VariableDefinition.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ class VariableDefinition extends DefinitionBase<
1414
) {
1515
super(DefinitionType.Variable, name, node, decl);
1616
}
17+
18+
public readonly isTypeDefinition = false;
19+
public readonly isVariableDefinition = true;
1720
}
1821

1922
export { VariableDefinition };

packages/scope-manager/src/referencer/ImportReferencer.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ class ImportReferencer extends Visitor {
1313
this.referencer = referencer;
1414
}
1515

16-
visitImport(
16+
static visit(
17+
referencer: Referencer,
18+
declaration: TSESTree.ImportDeclaration,
19+
): void {
20+
const importReferencer = new ImportReferencer(declaration, referencer);
21+
importReferencer.visit(declaration);
22+
}
23+
24+
protected visitImport(
1725
id: TSESTree.Identifier,
1826
specifier:
1927
| TSESTree.ImportDefaultSpecifier
@@ -28,17 +36,21 @@ class ImportReferencer extends Visitor {
2836
);
2937
}
3038

31-
ImportNamespaceSpecifier(node: TSESTree.ImportNamespaceSpecifier): void {
39+
protected ImportNamespaceSpecifier(
40+
node: TSESTree.ImportNamespaceSpecifier,
41+
): void {
3242
const local = node.local;
3343
this.visitImport(local, node);
3444
}
3545

36-
ImportDefaultSpecifier(node: TSESTree.ImportDefaultSpecifier): void {
46+
protected ImportDefaultSpecifier(
47+
node: TSESTree.ImportDefaultSpecifier,
48+
): void {
3749
const local = node.local;
3850
this.visitImport(local, node);
3951
}
4052

41-
ImportSpecifier(node: TSESTree.ImportSpecifier): void {
53+
protected ImportSpecifier(node: TSESTree.ImportSpecifier): void {
4254
const local = node.local;
4355
this.visitImport(local, node);
4456
}

packages/scope-manager/src/referencer/PatternVisitor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class PatternVisitor extends Visitor {
8282
}
8383

8484
ArrayPattern(pattern: TSESTree.ArrayPattern): void {
85-
for (let i = 0, iz = pattern.elements.length; i < iz; ++i) {
85+
for (let i = 0; i < pattern.elements.length; ++i) {
8686
const element = pattern.elements[i];
8787

8888
this.visit(element);

packages/scope-manager/src/referencer/Referencer.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,7 @@ class Referencer extends Visitor {
485485
'ImportDeclaration should appear when the mode is ES6 and in the module context.',
486486
);
487487

488-
const importer = new ImportReferencer(node, this);
489-
importer.visit(node);
488+
ImportReferencer.visit(this, node);
490489
}
491490

492491
protected LabeledStatement(node: TSESTree.LabeledStatement): void {
@@ -540,7 +539,7 @@ class Referencer extends Visitor {
540539
this.scopeManager.nestSwitchScope(node);
541540
}
542541

543-
for (let i = 0, iz = node.cases.length; i < iz; ++i) {
542+
for (let i = 0; i < node.cases.length; ++i) {
544543
this.visit(node.cases[i]);
545544
}
546545

@@ -563,7 +562,7 @@ class Referencer extends Visitor {
563562
? this.currentScope().variableScope
564563
: this.currentScope();
565564

566-
for (let i = 0, iz = node.declarations.length; i < iz; ++i) {
565+
for (let i = 0; i < node.declarations.length; ++i) {
567566
const decl = node.declarations[i];
568567
const init = decl.init;
569568

@@ -610,25 +609,22 @@ class Referencer extends Visitor {
610609
// TypeScript type nodes //
611610
///////////////////////////
612611

613-
protected visitTypeDeclaration(
614-
node:
615-
| TSESTree.TSTypeParameter
616-
| TSESTree.TSInterfaceDeclaration
617-
| TSESTree.TSTypeAliasDeclaration,
618-
): void {
619-
const typeReferencer = new TypeReferencer(this);
620-
typeReferencer.visit(node);
612+
protected visitType(node: TSESTree.Node | null | undefined): void {
613+
if (!node) {
614+
return;
615+
}
616+
TypeReferencer.visit(this, node);
621617
}
622618

623619
protected TSTypeAliasDeclaration(
624620
node: TSESTree.TSTypeAliasDeclaration,
625621
): void {
626-
this.visitTypeDeclaration(node);
622+
this.visitType(node);
627623
}
628624
protected TSInterfaceDeclaration(
629625
node: TSESTree.TSInterfaceDeclaration,
630626
): void {
631-
this.visitTypeDeclaration(node);
627+
this.visitType(node);
632628
}
633629
}
634630

packages/scope-manager/src/referencer/TypeReferencer.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class TypeReferencer extends Visitor {
1414
this.referencer = referencer;
1515
}
1616

17-
visitTypeDeclaration(
17+
protected visitTypeDeclaration(
1818
name: TSESTree.Identifier,
1919
node: TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeAliasDeclaration,
2020
): void {
@@ -30,30 +30,39 @@ class TypeReferencer extends Visitor {
3030
this.visit(node.typeParameters);
3131
}
3232

33-
TSTypeParameter(node: TSESTree.TSTypeParameter): void {
33+
static visit(referencer: Referencer, node: TSESTree.Node): void {
34+
const typeReferencer = new TypeReferencer(referencer);
35+
typeReferencer.visit(node);
36+
}
37+
38+
protected TSTypeParameter(node: TSESTree.TSTypeParameter): void {
3439
this.referencer
3540
.currentScope()
3641
.defineIdentifier(node.name, new TypeDefinition(node.name, node));
3742
}
38-
TSTypeAliasDeclaration(node: TSESTree.TSTypeAliasDeclaration): void {
43+
protected TSTypeAliasDeclaration(
44+
node: TSESTree.TSTypeAliasDeclaration,
45+
): void {
3946
this.visitTypeDeclaration(node.id, node);
4047
this.visit(node.typeAnnotation);
4148
this.referencer.close(node);
4249
}
43-
TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration): void {
50+
protected TSInterfaceDeclaration(
51+
node: TSESTree.TSInterfaceDeclaration,
52+
): void {
4453
this.visitTypeDeclaration(node.id, node);
4554
node.extends?.forEach(this.visit, this);
4655
node.implements?.forEach(this.visit, this);
4756
this.visit(node.body);
4857
this.referencer.close(node);
4958
}
5059

51-
Identifier(node: TSESTree.Identifier): void {
60+
protected Identifier(node: TSESTree.Identifier): void {
5261
this.referencer.currentScope().referenceType(node);
5362
}
5463

5564
// a type query `typeof foo` is a special case that references a _non-type_ variable,
56-
TSTypeQuery(node: TSESTree.TSTypeQuery): void {
65+
protected TSTypeQuery(node: TSESTree.TSTypeQuery): void {
5766
if (node.exprName.type === AST_NODE_TYPES.Identifier) {
5867
this.referencer.currentScope().referenceValue(node.exprName);
5968
} else {
@@ -65,7 +74,7 @@ class TypeReferencer extends Visitor {
6574
}
6675
}
6776

68-
TSQualifiedName(node: TSESTree.TSQualifiedName): void {
77+
protected TSQualifiedName(node: TSESTree.TSQualifiedName): void {
6978
this.visit(node.left);
7079
// we don't visit the right as it a name
7180
}

0 commit comments

Comments
 (0)