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

Skip to content

Commit 80487d5

Browse files
committed
feat: moar types support
1 parent c327102 commit 80487d5

File tree

127 files changed

+2783
-966
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+2783
-966
lines changed

packages/scope-manager/src/ScopeManager.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import {
44
BlockScope,
55
CatchScope,
66
ClassScope,
7+
ConditionalTypeScope,
78
ForScope,
89
FunctionExpressionNameScope,
910
FunctionScope,
11+
FunctionTypeScope,
1012
GlobalScope,
13+
MappedTypeScope,
1114
ModuleScope,
1215
Scope,
1316
SwitchScope,
@@ -170,6 +173,13 @@ class ScopeManager {
170173
return this.nestScope(new ClassScope(this, this.currentScope, node));
171174
}
172175

176+
public nestConditionalTypeScope(node: ConditionalTypeScope['block']): Scope {
177+
assert(this.currentScope);
178+
return this.nestScope(
179+
new ConditionalTypeScope(this, this.currentScope, node),
180+
);
181+
}
182+
173183
public nestForScope(node: ForScope['block']): Scope {
174184
assert(this.currentScope);
175185
return this.nestScope(new ForScope(this, this.currentScope, node));
@@ -194,10 +204,20 @@ class ScopeManager {
194204
);
195205
}
196206

207+
public nestFunctionTypeScope(node: FunctionTypeScope['block']): Scope {
208+
assert(this.currentScope);
209+
return this.nestScope(new FunctionTypeScope(this, this.currentScope, node));
210+
}
211+
197212
public nestGlobalScope(node: GlobalScope['block']): Scope {
198213
return this.nestScope(new GlobalScope(this, node));
199214
}
200215

216+
public nestMappedTypeScope(node: MappedTypeScope['block']): Scope {
217+
assert(this.currentScope);
218+
return this.nestScope(new MappedTypeScope(this, this.currentScope, node));
219+
}
220+
201221
public nestModuleScope(node: ModuleScope['block']): Scope {
202222
assert(this.currentScope);
203223
return this.nestScope(new ModuleScope(this, this.currentScope, node));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class Reference {
5555
*/
5656
public readonly writeExpr?: TSESTree.Node | null;
5757

58-
public maybeImplicitGlobal?: ReferenceImplicitGlobal | null;
58+
public readonly maybeImplicitGlobal?: ReferenceImplicitGlobal | null;
5959

6060
/**
6161
* True if this reference was created from a type context, false otherwise

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

Lines changed: 134 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,44 +19,158 @@ class TypeVisitor extends Visitor {
1919
typeReferencer.visit(node);
2020
}
2121

22-
protected visitTypeDeclaration(
23-
name: TSESTree.Identifier,
24-
node: TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeAliasDeclaration,
25-
): void {
26-
this.referencer
27-
.currentScope()
28-
.defineIdentifier(name, new TypeDefinition(name, node));
22+
///////////////////
23+
// Visit helpers //
24+
///////////////////
2925

26+
protected visitFunctionType(
27+
node:
28+
| TSESTree.TSCallSignatureDeclaration
29+
| TSESTree.TSConstructorType
30+
| TSESTree.TSConstructSignatureDeclaration
31+
| TSESTree.TSFunctionType
32+
| TSESTree.TSMethodSignature,
33+
): void {
3034
// type parameters cannot be referenced from outside their current scope
31-
this.referencer.scopeManager.nestTypeScope(node);
35+
if (node.typeParameters) {
36+
this.referencer.scopeManager.nestFunctionTypeScope(node);
37+
this.visit(node.typeParameters);
38+
}
3239

33-
this.visit(node.typeParameters);
40+
for (const param of node.params) {
41+
if (param.type == AST_NODE_TYPES.Identifier) {
42+
this.visit(param.typeAnnotation);
43+
}
44+
}
45+
this.visit(node.returnType);
46+
47+
if (node.typeParameters) {
48+
this.referencer.close(node);
49+
}
3450
}
3551

36-
protected TSTypeParameter(node: TSESTree.TSTypeParameter): void {
37-
this.referencer
38-
.currentScope()
39-
.defineIdentifier(node.name, new TypeDefinition(node.name, node));
52+
protected visitPropertyKey(
53+
node: TSESTree.TSMethodSignature | TSESTree.TSPropertySignature,
54+
): void {
55+
if (node.computed && node.key.type === AST_NODE_TYPES.Identifier) {
56+
this.referencer.currentScope().referenceValue(node.key);
57+
}
4058
}
41-
protected TSTypeAliasDeclaration(
42-
node: TSESTree.TSTypeAliasDeclaration,
59+
60+
/////////////////////
61+
// Visit selectors //
62+
/////////////////////
63+
64+
protected Identifier(node: TSESTree.Identifier): void {
65+
this.referencer.currentScope().referenceType(node);
66+
}
67+
68+
protected TSCallSignatureDeclaration(
69+
node: TSESTree.TSCallSignatureDeclaration,
4370
): void {
44-
this.visitTypeDeclaration(node.id, node);
45-
this.visit(node.typeAnnotation);
71+
this.visitFunctionType(node);
72+
}
73+
74+
protected TSConditionalType(node: TSESTree.TSConditionalType): void {
75+
// conditional types can define inferred type parameters
76+
// which are only accessible from inside the conditional parameter
77+
this.referencer.scopeManager.nestConditionalTypeScope(node);
78+
79+
this.visitChildren(node);
80+
4681
this.referencer.close(node);
4782
}
83+
84+
protected TSConstructorType(node: TSESTree.TSConstructorType): void {
85+
this.visitFunctionType(node);
86+
}
87+
88+
protected TSConstructSignatureDeclaration(
89+
node: TSESTree.TSConstructSignatureDeclaration,
90+
): void {
91+
this.visitFunctionType(node);
92+
}
93+
94+
protected TSFunctionType(node: TSESTree.TSFunctionType): void {
95+
this.visitFunctionType(node);
96+
}
97+
98+
protected TSIndexSignature(node: TSESTree.TSIndexSignature): void {
99+
for (const param of node.parameters) {
100+
if (param.type === AST_NODE_TYPES.Identifier) {
101+
this.visit(param.typeAnnotation);
102+
}
103+
}
104+
this.visit(node.typeAnnotation);
105+
}
106+
48107
protected TSInterfaceDeclaration(
49108
node: TSESTree.TSInterfaceDeclaration,
50109
): void {
51-
this.visitTypeDeclaration(node.id, node);
110+
this.referencer
111+
.currentScope()
112+
.defineIdentifier(node.id, new TypeDefinition(node.id, node));
113+
114+
// type parameters cannot be referenced from outside their current scope
115+
if (node.typeParameters) {
116+
this.referencer.scopeManager.nestTypeScope(node);
117+
this.visit(node.typeParameters);
118+
}
119+
52120
node.extends?.forEach(this.visit, this);
53121
node.implements?.forEach(this.visit, this);
54122
this.visit(node.body);
123+
124+
if (node.typeParameters) {
125+
this.referencer.close(node);
126+
}
127+
}
128+
129+
protected TSMappedType(node: TSESTree.TSMappedType): void {
130+
this.referencer.scopeManager.nestMappedTypeScope(node);
131+
this.visitChildren(node);
55132
this.referencer.close(node);
56133
}
57134

58-
protected Identifier(node: TSESTree.Identifier): void {
59-
this.referencer.currentScope().referenceType(node);
135+
protected TSMethodSignature(node: TSESTree.TSMethodSignature): void {
136+
this.visitPropertyKey(node);
137+
this.visitFunctionType(node);
138+
}
139+
140+
protected TSPropertySignature(node: TSESTree.TSPropertySignature): void {
141+
this.visitPropertyKey(node);
142+
this.visit(node.typeAnnotation);
143+
}
144+
145+
protected TSQualifiedName(node: TSESTree.TSQualifiedName): void {
146+
this.visit(node.left);
147+
// we don't visit the right as it a name on the thing, not a name to reference
148+
}
149+
150+
protected TSTypeAliasDeclaration(
151+
node: TSESTree.TSTypeAliasDeclaration,
152+
): void {
153+
this.referencer
154+
.currentScope()
155+
.defineIdentifier(node.id, new TypeDefinition(node.id, node));
156+
157+
// type parameters cannot be referenced from outside their current scope
158+
if (node.typeParameters) {
159+
this.referencer.scopeManager.nestTypeScope(node);
160+
this.visit(node.typeParameters);
161+
}
162+
163+
this.visit(node.typeAnnotation);
164+
165+
if (node.typeParameters) {
166+
this.referencer.close(node);
167+
}
168+
}
169+
170+
protected TSTypeParameter(node: TSESTree.TSTypeParameter): void {
171+
this.referencer
172+
.currentScope()
173+
.defineIdentifier(node.name, new TypeDefinition(node.name, node));
60174
}
61175

62176
// a type query `typeof foo` is a special case that references a _non-type_ variable,
@@ -71,11 +185,6 @@ class TypeVisitor extends Visitor {
71185
this.referencer.currentScope().referenceValue(expr);
72186
}
73187
}
74-
75-
protected TSQualifiedName(node: TSESTree.TSQualifiedName): void {
76-
this.visit(node.left);
77-
// we don't visit the right as it a name
78-
}
79188
}
80189

81190
export { TypeVisitor };
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { TSESTree } from '@typescript-eslint/experimental-utils';
2+
import { Scope } from './Scope';
3+
import { ScopeBase } from './ScopeBase';
4+
import { ScopeType } from './ScopeType';
5+
import { ScopeManager } from '../ScopeManager';
6+
7+
class ConditionalTypeScope extends ScopeBase<
8+
ScopeType.conditionalType,
9+
TSESTree.TSConditionalType,
10+
Scope
11+
> {
12+
constructor(
13+
scopeManager: ScopeManager,
14+
upperScope: ConditionalTypeScope['upper'],
15+
block: ConditionalTypeScope['block'],
16+
) {
17+
super(scopeManager, ScopeType.conditionalType, upperScope, block, false);
18+
}
19+
}
20+
21+
export { ConditionalTypeScope };
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { TSESTree } from '@typescript-eslint/experimental-utils';
2+
import { Scope } from './Scope';
3+
import { ScopeBase } from './ScopeBase';
4+
import { ScopeType } from './ScopeType';
5+
import { ScopeManager } from '../ScopeManager';
6+
7+
class FunctionTypeScope extends ScopeBase<
8+
ScopeType.functionType,
9+
| TSESTree.TSCallSignatureDeclaration
10+
| TSESTree.TSConstructorType
11+
| TSESTree.TSConstructSignatureDeclaration
12+
| TSESTree.TSFunctionType
13+
| TSESTree.TSMethodSignature,
14+
Scope
15+
> {
16+
constructor(
17+
scopeManager: ScopeManager,
18+
upperScope: FunctionTypeScope['upper'],
19+
block: FunctionTypeScope['block'],
20+
) {
21+
super(scopeManager, ScopeType.functionType, upperScope, block, false);
22+
}
23+
}
24+
25+
export { FunctionTypeScope };
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { TSESTree } from '@typescript-eslint/experimental-utils';
2+
import { Scope } from './Scope';
3+
import { ScopeBase } from './ScopeBase';
4+
import { ScopeType } from './ScopeType';
5+
import { ScopeManager } from '../ScopeManager';
6+
7+
class MappedTypeScope extends ScopeBase<
8+
ScopeType.mappedType,
9+
TSESTree.TSMappedType,
10+
Scope
11+
> {
12+
constructor(
13+
scopeManager: ScopeManager,
14+
upperScope: MappedTypeScope['upper'],
15+
block: MappedTypeScope['block'],
16+
) {
17+
super(scopeManager, ScopeType.mappedType, upperScope, block, false);
18+
}
19+
}
20+
21+
export { MappedTypeScope };
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { BlockScope } from './BlockScope';
22
import { CatchScope } from './CatchScope';
33
import { ClassScope } from './ClassScope';
4+
import { ConditionalTypeScope } from './ConditionalTypeScope';
45
import { ForScope } from './ForScope';
56
import { FunctionExpressionNameScope } from './FunctionExpressionNameScope';
67
import { FunctionScope } from './FunctionScope';
8+
import { FunctionTypeScope } from './FunctionTypeScope';
79
import { GlobalScope } from './GlobalScope';
10+
import { MappedTypeScope } from './MappedTypeScope';
811
import { ModuleScope } from './ModuleScope';
912
import { SwitchScope } from './SwitchScope';
1013
import { TypeScope } from './TypeScope';
@@ -14,15 +17,16 @@ type Scope =
1417
| BlockScope
1518
| CatchScope
1619
| ClassScope
20+
| ConditionalTypeScope
1721
| ForScope
1822
| FunctionExpressionNameScope
1923
| FunctionScope
24+
| FunctionTypeScope
2025
| GlobalScope
26+
| MappedTypeScope
2127
| ModuleScope
2228
| SwitchScope
2329
| TypeScope
2430
| WithScope;
2531

26-
type BlockNode = Scope['block'];
27-
28-
export { BlockNode, Scope };
32+
export { Scope };

packages/scope-manager/src/scope/ScopeBase.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { FunctionScope } from './FunctionScope';
66
import { GlobalScope } from './GlobalScope';
77
import { ScopeType } from './ScopeType';
88
import { ScopeManager } from '../ScopeManager';
9-
import { BlockNode, Scope } from './Scope';
9+
import { Scope } from './Scope';
1010
import { ModuleScope } from './ModuleScope';
1111
import { assert } from '../assert';
1212
import { Definition, DefinitionType } from '../definition';
@@ -23,7 +23,7 @@ import { Variable } from '../Variable';
2323
*/
2424
function isStrictScope(
2525
scope: Scope,
26-
block: BlockNode,
26+
block: TSESTree.Node,
2727
isMethodDefinition: boolean,
2828
): boolean {
2929
let body: TSESTree.BlockStatement | TSESTree.Program | null | undefined;
@@ -37,7 +37,13 @@ function isStrictScope(
3737
return true;
3838
}
3939

40-
if (scope.type === ScopeType.class || scope.type === ScopeType.module) {
40+
if (
41+
scope.type === ScopeType.class ||
42+
scope.type === ScopeType.module ||
43+
scope.type === ScopeType.type ||
44+
scope.type === ScopeType.conditionalType ||
45+
scope.type === ScopeType.functionType
46+
) {
4147
return true;
4248
}
4349

@@ -130,10 +136,10 @@ function shouldBeStaticallyClosed(def: Definition): boolean {
130136

131137
const generator = createIdGenerator();
132138

133-
type AnyScope = ScopeBase<ScopeType, BlockNode, Scope | null>;
139+
type AnyScope = ScopeBase<ScopeType, TSESTree.Node, Scope | null>;
134140
abstract class ScopeBase<
135141
TType extends ScopeType,
136-
TBlock extends BlockNode,
142+
TBlock extends TSESTree.Node,
137143
TUpper extends Scope | null
138144
> {
139145
/**

0 commit comments

Comments
 (0)