@@ -64,6 +64,11 @@ namespace ts {
64
64
undefinedSymbol.declarations = [];
65
65
const argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments");
66
66
67
+ // for public members that accept a Node or one of its subtypes, we must guard against
68
+ // synthetic nodes created during transformations by calling `getParseTreeNode`.
69
+ // for most of these, we perform the guard only on `checker` to avoid any possible
70
+ // extra cost of calling `getParseTreeNode` when calling these functions from inside the
71
+ // checker.
67
72
const checker: TypeChecker = {
68
73
getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"),
69
74
getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
@@ -74,8 +79,15 @@ namespace ts {
74
79
isUnknownSymbol: symbol => symbol === unknownSymbol,
75
80
getDiagnostics,
76
81
getGlobalDiagnostics,
77
- getTypeOfSymbolAtLocation,
78
- getSymbolsOfParameterPropertyDeclaration,
82
+ getTypeOfSymbolAtLocation: (symbol, location) => {
83
+ location = getParseTreeNode(location);
84
+ return location ? getTypeOfSymbolAtLocation(symbol, location) : unknownType;
85
+ },
86
+ getSymbolsOfParameterPropertyDeclaration: (parameter, parameterName) => {
87
+ parameter = getParseTreeNode(parameter, isParameter);
88
+ Debug.assert(parameter !== undefined, "Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
89
+ return getSymbolsOfParameterPropertyDeclaration(parameter, parameterName);
90
+ },
79
91
getDeclaredTypeOfSymbol,
80
92
getPropertiesOfType,
81
93
getPropertyOfType,
@@ -85,37 +97,88 @@ namespace ts {
85
97
getBaseTypes,
86
98
getBaseTypeOfLiteralType,
87
99
getWidenedType,
88
- getTypeFromTypeNode,
100
+ getTypeFromTypeNode: node => {
101
+ node = getParseTreeNode(node, isTypeNode);
102
+ return node ? getTypeFromTypeNode(node) : unknownType;
103
+ },
89
104
getParameterType: getTypeAtPosition,
90
105
getReturnTypeOfSignature,
91
106
getNonNullableType,
92
- getSymbolsInScope,
93
- getSymbolAtLocation,
94
- getShorthandAssignmentValueSymbol,
95
- getExportSpecifierLocalTargetSymbol,
96
- getTypeAtLocation: getTypeOfNode,
97
- getPropertySymbolOfDestructuringAssignment,
98
- signatureToString,
99
- typeToString,
107
+ getSymbolsInScope: (location, meaning) => {
108
+ location = getParseTreeNode(location);
109
+ return location ? getSymbolsInScope(location, meaning) : [];
110
+ },
111
+ getSymbolAtLocation: node => {
112
+ node = getParseTreeNode(node);
113
+ return node ? getSymbolAtLocation(node) : undefined;
114
+ },
115
+ getShorthandAssignmentValueSymbol: node => {
116
+ node = getParseTreeNode(node);
117
+ return node ? getShorthandAssignmentValueSymbol(node) : undefined;
118
+ },
119
+ getExportSpecifierLocalTargetSymbol: node => {
120
+ node = getParseTreeNode(node, isExportSpecifier);
121
+ return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
122
+ },
123
+ getTypeAtLocation: node => {
124
+ node = getParseTreeNode(node);
125
+ return node ? getTypeOfNode(node) : unknownType;
126
+ },
127
+ getPropertySymbolOfDestructuringAssignment: location => {
128
+ location = getParseTreeNode(location, isIdentifier);
129
+ return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
130
+ },
131
+ signatureToString: (signature, enclosingDeclaration?, flags?, kind?) => {
132
+ return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind);
133
+ },
134
+ typeToString: (type, enclosingDeclaration?, flags?) => {
135
+ return typeToString(type, getParseTreeNode(enclosingDeclaration), flags);
136
+ },
100
137
getSymbolDisplayBuilder,
101
- symbolToString,
138
+ symbolToString: (symbol, enclosingDeclaration?, meaning?) => {
139
+ return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning);
140
+ },
102
141
getAugmentedPropertiesOfType,
103
142
getRootSymbols,
104
- getContextualType,
143
+ getContextualType: node => {
144
+ node = getParseTreeNode(node, isExpression)
145
+ return node ? getContextualType(node) : undefined;
146
+ },
105
147
getFullyQualifiedName,
106
- getResolvedSignature,
107
- getConstantValue,
108
- isValidPropertyAccess,
109
- getSignatureFromDeclaration,
110
- isImplementationOfOverload,
148
+ getResolvedSignature: (node, candidatesOutArray?) => {
149
+ node = getParseTreeNode(node, isCallLikeExpression);
150
+ return node ? getResolvedSignature(node, candidatesOutArray) : undefined;
151
+ },
152
+ getConstantValue: node => {
153
+ node = getParseTreeNode(node, canHaveConstantValue);
154
+ return node ? getConstantValue(node) : undefined;
155
+ },
156
+ isValidPropertyAccess: (node, propertyName) => {
157
+ node = getParseTreeNode(node, isPropertyAccessOrQualifiedName);
158
+ return node ? isValidPropertyAccess(node, propertyName) : false;
159
+ },
160
+ getSignatureFromDeclaration: declaration => {
161
+ declaration = getParseTreeNode(declaration, isFunctionLike);
162
+ return declaration ? getSignatureFromDeclaration(declaration) : undefined;
163
+ },
164
+ isImplementationOfOverload: node => {
165
+ node = getParseTreeNode(node, isFunctionLike);
166
+ return node ? isImplementationOfOverload(node) : undefined;
167
+ },
111
168
getAliasedSymbol: resolveAlias,
112
169
getEmitResolver,
113
170
getExportsOfModule: getExportsOfModuleAsArray,
114
171
getExportsAndPropertiesOfModule,
115
172
getAmbientModules,
116
- getAllAttributesTypeFromJsxOpeningLikeElement,
173
+ getAllAttributesTypeFromJsxOpeningLikeElement: node => {
174
+ node = getParseTreeNode(node, isJsxOpeningLikeElement);
175
+ return node ? getAllAttributesTypeFromJsxOpeningLikeElement(node) : undefined;
176
+ },
117
177
getJsxIntrinsicTagNames,
118
- isOptionalParameter,
178
+ isOptionalParameter: node => {
179
+ node = getParseTreeNode(node, isParameter);
180
+ return node ? isOptionalParameter(node) : false;
181
+ },
119
182
tryGetMemberInModuleExports,
120
183
tryFindAmbientModuleWithoutAugmentations: moduleName => {
121
184
// we deliberately exclude augmentations
@@ -20657,14 +20720,14 @@ namespace ts {
20657
20720
}
20658
20721
20659
20722
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
20660
- const symbols = createMap<Symbol>();
20661
- let memberFlags: ModifierFlags = ModifierFlags.None;
20662
-
20663
20723
if (isInsideWithStatementBody(location)) {
20664
20724
// We cannot answer semantic questions within a with block, do not proceed any further
20665
20725
return [];
20666
20726
}
20667
20727
20728
+ const symbols = createMap<Symbol>();
20729
+ let memberFlags: ModifierFlags = ModifierFlags.None;
20730
+
20668
20731
populateSymbols();
20669
20732
20670
20733
return symbolsToArray(symbols);
@@ -20931,6 +20994,7 @@ namespace ts {
20931
20994
if (node.kind === SyntaxKind.SourceFile) {
20932
20995
return isExternalModule(<SourceFile>node) ? getMergedSymbol(node.symbol) : undefined;
20933
20996
}
20997
+
20934
20998
if (isInsideWithStatementBody(node)) {
20935
20999
// We cannot answer semantic questions within a with block, do not proceed any further
20936
21000
return undefined;
@@ -21381,12 +21445,6 @@ namespace ts {
21381
21445
}
21382
21446
21383
21447
function isValueAliasDeclaration(node: Node): boolean {
21384
- node = getParseTreeNode(node);
21385
- if (node === undefined) {
21386
- // A synthesized node comes from an emit transformation and is always a value.
21387
- return true;
21388
- }
21389
-
21390
21448
switch (node.kind) {
21391
21449
case SyntaxKind.ImportEqualsDeclaration:
21392
21450
case SyntaxKind.ImportClause:
@@ -21433,12 +21491,6 @@ namespace ts {
21433
21491
}
21434
21492
21435
21493
function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean {
21436
- node = getParseTreeNode(node);
21437
- // Purely synthesized nodes are always emitted.
21438
- if (node === undefined) {
21439
- return true;
21440
- }
21441
-
21442
21494
if (isAliasSymbolDeclaration(node)) {
21443
21495
const symbol = getSymbolOfNode(node);
21444
21496
if (symbol && getSymbolLinks(symbol).referenced) {
@@ -21481,15 +21533,24 @@ namespace ts {
21481
21533
}
21482
21534
21483
21535
function getNodeCheckFlags(node: Node): NodeCheckFlags {
21484
- node = getParseTreeNode(node);
21485
- return node ? getNodeLinks(node).flags : undefined;
21536
+ return getNodeLinks(node).flags;
21486
21537
}
21487
21538
21488
21539
function getEnumMemberValue(node: EnumMember): number {
21489
21540
computeEnumMemberValues(<EnumDeclaration>node.parent);
21490
21541
return getNodeLinks(node).enumMemberValue;
21491
21542
}
21492
21543
21544
+ function canHaveConstantValue(node: Node): node is EnumMember | PropertyAccessExpression | ElementAccessExpression {
21545
+ switch (node.kind) {
21546
+ case SyntaxKind.EnumMember:
21547
+ case SyntaxKind.PropertyAccessExpression:
21548
+ case SyntaxKind.ElementAccessExpression:
21549
+ return true;
21550
+ }
21551
+ return false;
21552
+ }
21553
+
21493
21554
function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number {
21494
21555
if (node.kind === SyntaxKind.EnumMember) {
21495
21556
return getEnumMemberValue(<EnumMember>node);
@@ -21671,10 +21732,21 @@ namespace ts {
21671
21732
getReferencedImportDeclaration,
21672
21733
getReferencedDeclarationWithCollidingName,
21673
21734
isDeclarationWithCollidingName,
21674
- isValueAliasDeclaration,
21735
+ isValueAliasDeclaration: node => {
21736
+ node = getParseTreeNode(node);
21737
+ // Synthesized nodes are always treated like values.
21738
+ return node ? isValueAliasDeclaration(node) : true;
21739
+ },
21675
21740
hasGlobalName,
21676
- isReferencedAliasDeclaration,
21677
- getNodeCheckFlags,
21741
+ isReferencedAliasDeclaration: (node, checkChildren?) => {
21742
+ node = getParseTreeNode(node);
21743
+ // Synthesized nodes are always treated as referenced.
21744
+ return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
21745
+ },
21746
+ getNodeCheckFlags: node => {
21747
+ node = getParseTreeNode(node);
21748
+ return node ? getNodeCheckFlags(node) : undefined;
21749
+ },
21678
21750
isTopLevelValueImportEqualsWithEntityName,
21679
21751
isDeclarationVisible,
21680
21752
isImplementationOfOverload,
@@ -21685,7 +21757,10 @@ namespace ts {
21685
21757
writeBaseConstructorTypeOfClass,
21686
21758
isSymbolAccessible,
21687
21759
isEntityNameVisible,
21688
- getConstantValue,
21760
+ getConstantValue: node => {
21761
+ node = getParseTreeNode(node, canHaveConstantValue);
21762
+ return node ? getConstantValue(node) : undefined;
21763
+ },
21689
21764
collectLinkedAliases,
21690
21765
getReferencedValueDeclaration,
21691
21766
getTypeReferenceSerializationKind,
0 commit comments