@@ -64,6 +64,11 @@ namespace ts {
64
64
undefinedSymbol.declarations = [];
65
65
const argumentsSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "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,46 +79,104 @@ 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,
82
94
getIndexInfoOfType,
83
95
getSignaturesOfType,
84
96
getIndexTypeOfType,
85
97
getBaseTypes,
86
- getTypeFromTypeNode,
98
+ getTypeFromTypeNode: node => {
99
+ node = getParseTreeNode(node, isTypeNode);
100
+ return node ? getTypeFromTypeNode(node) : unknownType;
101
+ },
87
102
getParameterType: getTypeAtPosition,
88
103
getReturnTypeOfSignature,
89
104
getNonNullableType,
90
- getSymbolsInScope,
91
- getSymbolAtLocation,
92
- getShorthandAssignmentValueSymbol,
93
- getExportSpecifierLocalTargetSymbol,
94
- getTypeAtLocation: getTypeOfNode,
95
- getPropertySymbolOfDestructuringAssignment,
96
- signatureToString,
97
- typeToString,
105
+ getSymbolsInScope: (location, meaning) => {
106
+ location = getParseTreeNode(location);
107
+ return location ? getSymbolsInScope(location, meaning) : [];
108
+ },
109
+ getSymbolAtLocation: node => {
110
+ node = getParseTreeNode(node);
111
+ return node ? getSymbolAtLocation(node) : undefined;
112
+ },
113
+ getShorthandAssignmentValueSymbol: node => {
114
+ node = getParseTreeNode(node);
115
+ return node ? getShorthandAssignmentValueSymbol(node) : undefined;
116
+ },
117
+ getExportSpecifierLocalTargetSymbol: node => {
118
+ node = getParseTreeNode(node, isExportSpecifier);
119
+ return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
120
+ },
121
+ getTypeAtLocation: node => {
122
+ node = getParseTreeNode(node);
123
+ return node ? getTypeOfNode(node) : unknownType;
124
+ },
125
+ getPropertySymbolOfDestructuringAssignment: location => {
126
+ location = getParseTreeNode(location, isIdentifier);
127
+ return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
128
+ },
129
+ signatureToString: (signature, enclosingDeclaration?, flags?, kind?) => {
130
+ return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind);
131
+ },
132
+ typeToString: (type, enclosingDeclaration?, flags?) => {
133
+ return typeToString(type, getParseTreeNode(enclosingDeclaration), flags);
134
+ },
98
135
getSymbolDisplayBuilder,
99
- symbolToString,
136
+ symbolToString: (symbol, enclosingDeclaration?, meaning?) => {
137
+ return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning);
138
+ },
100
139
getAugmentedPropertiesOfType,
101
140
getRootSymbols,
102
- getContextualType,
141
+ getContextualType: node => {
142
+ node = getParseTreeNode(node, isExpression)
143
+ return node ? getContextualType(node) : undefined;
144
+ },
103
145
getFullyQualifiedName,
104
- getResolvedSignature,
105
- getConstantValue,
106
- isValidPropertyAccess,
107
- getSignatureFromDeclaration,
108
- isImplementationOfOverload,
146
+ getResolvedSignature: (node, candidatesOutArray?) => {
147
+ node = getParseTreeNode(node, isCallLikeExpression);
148
+ return node ? getResolvedSignature(node, candidatesOutArray) : undefined;
149
+ },
150
+ getConstantValue: node => {
151
+ node = getParseTreeNode(node, canHaveConstantValue);
152
+ return node ? getConstantValue(node) : undefined;
153
+ },
154
+ isValidPropertyAccess: (node, propertyName) => {
155
+ node = getParseTreeNode(node, isPropertyAccessOrQualifiedName);
156
+ return node ? isValidPropertyAccess(node, propertyName) : false;
157
+ },
158
+ getSignatureFromDeclaration: declaration => {
159
+ declaration = getParseTreeNode(declaration, isFunctionLike);
160
+ return declaration ? getSignatureFromDeclaration(declaration) : undefined;
161
+ },
162
+ isImplementationOfOverload: node => {
163
+ node = getParseTreeNode(node, isFunctionLike);
164
+ return node ? isImplementationOfOverload(node) : undefined;
165
+ },
109
166
getAliasedSymbol: resolveAlias,
110
167
getEmitResolver,
111
168
getExportsOfModule: getExportsOfModuleAsArray,
112
169
getExportsAndPropertiesOfModule,
113
170
getAmbientModules,
114
- getJsxElementAttributesType,
171
+ getJsxElementAttributesType: node => {
172
+ node = getParseTreeNode(node, isJsxOpeningLikeElement);
173
+ return node ? getJsxElementAttributesType(node) : undefined;
174
+ },
115
175
getJsxIntrinsicTagNames,
116
- isOptionalParameter,
176
+ isOptionalParameter: node => {
177
+ node = getParseTreeNode(node, isParameter);
178
+ return node ? isOptionalParameter(node) : false;
179
+ },
117
180
tryGetMemberInModuleExports,
118
181
tryFindAmbientModuleWithoutAugmentations: moduleName => {
119
182
// we deliberately exclude augmentations
@@ -19819,14 +19882,14 @@ namespace ts {
19819
19882
}
19820
19883
19821
19884
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
19822
- const symbols = createMap<Symbol>();
19823
- let memberFlags: ModifierFlags = ModifierFlags.None;
19824
-
19825
19885
if (isInsideWithStatementBody(location)) {
19826
19886
// We cannot answer semantic questions within a with block, do not proceed any further
19827
19887
return [];
19828
19888
}
19829
19889
19890
+ const symbols = createMap<Symbol>();
19891
+ let memberFlags: ModifierFlags = ModifierFlags.None;
19892
+
19830
19893
populateSymbols();
19831
19894
19832
19895
return symbolsToArray(symbols);
@@ -20086,6 +20149,7 @@ namespace ts {
20086
20149
if (node.kind === SyntaxKind.SourceFile) {
20087
20150
return isExternalModule(<SourceFile>node) ? getMergedSymbol(node.symbol) : undefined;
20088
20151
}
20152
+
20089
20153
if (isInsideWithStatementBody(node)) {
20090
20154
// We cannot answer semantic questions within a with block, do not proceed any further
20091
20155
return undefined;
@@ -20536,12 +20600,6 @@ namespace ts {
20536
20600
}
20537
20601
20538
20602
function isValueAliasDeclaration(node: Node): boolean {
20539
- node = getParseTreeNode(node);
20540
- if (node === undefined) {
20541
- // A synthesized node comes from an emit transformation and is always a value.
20542
- return true;
20543
- }
20544
-
20545
20603
switch (node.kind) {
20546
20604
case SyntaxKind.ImportEqualsDeclaration:
20547
20605
case SyntaxKind.ImportClause:
@@ -20588,12 +20646,6 @@ namespace ts {
20588
20646
}
20589
20647
20590
20648
function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean {
20591
- node = getParseTreeNode(node);
20592
- // Purely synthesized nodes are always emitted.
20593
- if (node === undefined) {
20594
- return true;
20595
- }
20596
-
20597
20649
if (isAliasSymbolDeclaration(node)) {
20598
20650
const symbol = getSymbolOfNode(node);
20599
20651
if (symbol && getSymbolLinks(symbol).referenced) {
@@ -20629,15 +20681,24 @@ namespace ts {
20629
20681
}
20630
20682
20631
20683
function getNodeCheckFlags(node: Node): NodeCheckFlags {
20632
- node = getParseTreeNode(node);
20633
- return node ? getNodeLinks(node).flags : undefined;
20684
+ return getNodeLinks(node).flags;
20634
20685
}
20635
20686
20636
20687
function getEnumMemberValue(node: EnumMember): number {
20637
20688
computeEnumMemberValues(<EnumDeclaration>node.parent);
20638
20689
return getNodeLinks(node).enumMemberValue;
20639
20690
}
20640
20691
20692
+ function canHaveConstantValue(node: Node): node is EnumMember | PropertyAccessExpression | ElementAccessExpression {
20693
+ switch (node.kind) {
20694
+ case SyntaxKind.EnumMember:
20695
+ case SyntaxKind.PropertyAccessExpression:
20696
+ case SyntaxKind.ElementAccessExpression:
20697
+ return true;
20698
+ }
20699
+ return false;
20700
+ }
20701
+
20641
20702
function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number {
20642
20703
if (node.kind === SyntaxKind.EnumMember) {
20643
20704
return getEnumMemberValue(<EnumMember>node);
@@ -20814,10 +20875,21 @@ namespace ts {
20814
20875
getReferencedImportDeclaration,
20815
20876
getReferencedDeclarationWithCollidingName,
20816
20877
isDeclarationWithCollidingName,
20817
- isValueAliasDeclaration,
20878
+ isValueAliasDeclaration: node => {
20879
+ node = getParseTreeNode(node);
20880
+ // Synthesized nodes are always treated like values.
20881
+ return node ? isValueAliasDeclaration(node) : true;
20882
+ },
20818
20883
hasGlobalName,
20819
- isReferencedAliasDeclaration,
20820
- getNodeCheckFlags,
20884
+ isReferencedAliasDeclaration: (node, checkChildren?) => {
20885
+ node = getParseTreeNode(node);
20886
+ // Synthesized nodes are always treated as referenced.
20887
+ return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
20888
+ },
20889
+ getNodeCheckFlags: node => {
20890
+ node = getParseTreeNode(node);
20891
+ return node ? getNodeCheckFlags(node) : undefined;
20892
+ },
20821
20893
isTopLevelValueImportEqualsWithEntityName,
20822
20894
isDeclarationVisible,
20823
20895
isImplementationOfOverload,
@@ -20827,7 +20899,10 @@ namespace ts {
20827
20899
writeBaseConstructorTypeOfClass,
20828
20900
isSymbolAccessible,
20829
20901
isEntityNameVisible,
20830
- getConstantValue,
20902
+ getConstantValue: node => {
20903
+ node = getParseTreeNode(node, canHaveConstantValue);
20904
+ return node ? getConstantValue(node) : undefined;
20905
+ },
20831
20906
collectLinkedAliases,
20832
20907
getReferencedValueDeclaration,
20833
20908
getTypeReferenceSerializationKind,
0 commit comments