@@ -272,6 +272,8 @@ import {
272
272
getFirstIdentifier,
273
273
getFunctionFlags,
274
274
getHostSignatureFromJSDoc,
275
+ getIdentifierGeneratedImportReference,
276
+ getIdentifierTypeArguments,
275
277
getImmediatelyInvokedFunctionExpression,
276
278
getInitializerOfBinaryExpression,
277
279
getInterfaceBaseTypeNodes,
@@ -375,6 +377,7 @@ import {
375
377
hasSyntacticModifiers,
376
378
HeritageClause,
377
379
Identifier,
380
+ identifierToKeywordKind,
378
381
IdentifierTypePredicate,
379
382
idText,
380
383
IfStatement,
@@ -890,11 +893,13 @@ import {
890
893
ReverseMappedType,
891
894
sameMap,
892
895
SatisfiesExpression,
896
+ scanTokenAtPosition,
893
897
ScriptKind,
894
898
ScriptTarget,
895
899
SetAccessorDeclaration,
896
900
setCommentRange,
897
901
setEmitFlags,
902
+ setIdentifierTypeArguments,
898
903
setNodeFlags,
899
904
setOriginalNode,
900
905
setParent,
@@ -6794,12 +6799,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
6794
6799
let qualifier = root.qualifier;
6795
6800
if (qualifier) {
6796
6801
if (isIdentifier(qualifier)) {
6797
- qualifier = factory.updateIdentifier(qualifier, typeArguments);
6802
+ if (typeArguments !== getIdentifierTypeArguments(qualifier)) {
6803
+ qualifier = setIdentifierTypeArguments(factory.cloneNode(qualifier), typeArguments);
6804
+ }
6798
6805
}
6799
6806
else {
6800
- qualifier = factory.updateQualifiedName(qualifier,
6801
- qualifier.left,
6802
- factory.updateIdentifier(qualifier.right, typeArguments));
6807
+ if (typeArguments !== getIdentifierTypeArguments(qualifier.right)) {
6808
+ qualifier = factory.updateQualifiedName(qualifier,
6809
+ qualifier.left,
6810
+ setIdentifierTypeArguments(factory.cloneNode(qualifier.right), typeArguments));
6811
+ }
6803
6812
}
6804
6813
}
6805
6814
typeArguments = ref.typeArguments;
@@ -6821,12 +6830,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
6821
6830
let typeArguments = root.typeArguments;
6822
6831
let typeName = root.typeName;
6823
6832
if (isIdentifier(typeName)) {
6824
- typeName = factory.updateIdentifier(typeName, typeArguments);
6833
+ if (typeArguments !== getIdentifierTypeArguments(typeName)) {
6834
+ typeName = setIdentifierTypeArguments(factory.cloneNode(typeName), typeArguments);
6835
+ }
6825
6836
}
6826
6837
else {
6827
- typeName = factory.updateQualifiedName(typeName,
6828
- typeName.left,
6829
- factory.updateIdentifier(typeName.right, typeArguments));
6838
+ if (typeArguments !== getIdentifierTypeArguments(typeName.right)) {
6839
+ typeName = factory.updateQualifiedName(typeName,
6840
+ typeName.left,
6841
+ setIdentifierTypeArguments(factory.cloneNode(typeName.right), typeArguments));
6842
+ }
6830
6843
}
6831
6844
typeArguments = ref.typeArguments;
6832
6845
// then move qualifiers
@@ -7544,7 +7557,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
7544
7557
if (!nonRootParts || isEntityName(nonRootParts)) {
7545
7558
if (nonRootParts) {
7546
7559
const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
7547
- lastId. typeArguments = undefined;
7560
+ setIdentifierTypeArguments( lastId, /* typeArguments*/ undefined) ;
7548
7561
}
7549
7562
return factory.createImportTypeNode(lit, assertion, nonRootParts as EntityName, typeParameterNodes as readonly TypeNode[], isTypeOf);
7550
7563
}
@@ -7564,8 +7577,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
7564
7577
}
7565
7578
else {
7566
7579
const lastId = isIdentifier(entityName) ? entityName : entityName.right;
7567
- const lastTypeArgs = lastId.typeArguments ;
7568
- lastId. typeArguments = undefined;
7580
+ const lastTypeArgs = getIdentifierTypeArguments( lastId) ;
7581
+ setIdentifierTypeArguments( lastId, /* typeArguments*/ undefined) ;
7569
7582
return factory.createTypeReferenceNode(entityName, lastTypeArgs as NodeArray<TypeNode>);
7570
7583
}
7571
7584
@@ -7619,7 +7632,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
7619
7632
}
7620
7633
}
7621
7634
7622
- const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
7635
+ const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
7636
+ if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
7623
7637
identifier.symbol = symbol;
7624
7638
7625
7639
if (index > stopper) {
@@ -7664,7 +7678,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
7664
7678
text = `${rawtext}_${i}`;
7665
7679
}
7666
7680
if (text !== rawtext) {
7667
- result = factory.createIdentifier(text, result.typeArguments);
7681
+ const typeArguments = getIdentifierTypeArguments(result);
7682
+ result = factory.createIdentifier(text);
7683
+ setIdentifierTypeArguments(result, typeArguments);
7668
7684
}
7669
7685
// avoiding iterations of the above loop turns out to be worth it when `i` starts to get large, so we cache the max
7670
7686
// `i` we've used thus far, to save work later
@@ -7699,7 +7715,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
7699
7715
context.flags ^= NodeBuilderFlags.InInitialEntityName;
7700
7716
}
7701
7717
7702
- const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
7718
+ const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
7719
+ if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
7703
7720
identifier.symbol = symbol;
7704
7721
7705
7722
return index > 0 ? factory.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
@@ -7728,7 +7745,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
7728
7745
return factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context));
7729
7746
}
7730
7747
if (index === 0 || canUsePropertyAccess(symbolName, languageVersion)) {
7731
- const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
7748
+ const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
7749
+ if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
7732
7750
identifier.symbol = symbol;
7733
7751
7734
7752
return index > 0 ? factory.createPropertyAccessExpression(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier;
@@ -7746,8 +7764,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
7746
7764
expression = factory.createNumericLiteral(+symbolName);
7747
7765
}
7748
7766
if (!expression) {
7749
- expression = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
7750
- (expression as Identifier).symbol = symbol;
7767
+ const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
7768
+ if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
7769
+ identifier.symbol = symbol;
7770
+ expression = identifier;
7751
7771
}
7752
7772
return factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression);
7753
7773
}
@@ -23215,15 +23235,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
23215
23235
break;
23216
23236
case SyntaxKind.Parameter:
23217
23237
const param = declaration as ParameterDeclaration;
23218
- if (isIdentifier(param.name) &&
23219
- (isCallSignatureDeclaration(param.parent) || isMethodSignature(param.parent) || isFunctionTypeNode(param.parent)) &&
23220
- param.parent.parameters.indexOf(param) > -1 &&
23221
- (resolveName(param, param.name.escapedText, SymbolFlags.Type, undefined, param.name.escapedText, /*isUse*/ true) ||
23222
- param.name.originalKeywordKind && isTypeNodeKind(param.name.originalKeywordKind))) {
23223
- const newName = "arg" + param.parent.parameters.indexOf(param);
23224
- const typeName = declarationNameToString(param.name) + (param.dotDotDotToken ? "[]" : "");
23225
- errorOrSuggestion(noImplicitAny, declaration, Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName);
23226
- return;
23238
+ if (isIdentifier(param.name)) {
23239
+ const originalKeywordKind = identifierToKeywordKind(param.name);
23240
+ if ((isCallSignatureDeclaration(param.parent) || isMethodSignature(param.parent) || isFunctionTypeNode(param.parent)) &&
23241
+ param.parent.parameters.indexOf(param) > -1 &&
23242
+ (resolveName(param, param.name.escapedText, SymbolFlags.Type, undefined, param.name.escapedText, /*isUse*/ true) ||
23243
+ originalKeywordKind && isTypeNodeKind(originalKeywordKind))) {
23244
+ const newName = "arg" + param.parent.parameters.indexOf(param);
23245
+ const typeName = declarationNameToString(param.name) + (param.dotDotDotToken ? "[]" : "");
23246
+ errorOrSuggestion(noImplicitAny, declaration, Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName);
23247
+ return;
23248
+ }
23227
23249
}
23228
23250
diagnostic = (declaration as ParameterDeclaration).dotDotDotToken ?
23229
23251
noImplicitAny ? Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage :
@@ -37483,8 +37505,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
37483
37505
37484
37506
function checkTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments) {
37485
37507
checkGrammarTypeArguments(node, node.typeArguments);
37486
- if (node.kind === SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !isInJSFile(node) && !isInJSDoc(node)) {
37487
- grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
37508
+ if (node.kind === SyntaxKind.TypeReference && !isInJSFile(node) && !isInJSDoc(node) && node.typeArguments && node.typeName.end !== node.typeArguments.pos) {
37509
+ // If there was a token between the type name and the type arguments, check if it was a DotToken
37510
+ const sourceFile = getSourceFileOfNode(node);
37511
+ if (scanTokenAtPosition(sourceFile, node.typeName.end) === SyntaxKind.DotToken) {
37512
+ grammarErrorAtPos(node, skipTrivia(sourceFile.text, node.typeName.end), 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
37513
+ }
37488
37514
}
37489
37515
forEach(node.typeArguments, checkSourceElement);
37490
37516
const type = getTypeFromTypeReference(node);
@@ -44622,8 +44648,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
44622
44648
// When resolved as an expression identifier, if the given node references an import, return the declaration of
44623
44649
// that import. Otherwise, return undefined.
44624
44650
function getReferencedImportDeclaration(nodeIn: Identifier): Declaration | undefined {
44625
- if (nodeIn.generatedImportReference) {
44626
- return nodeIn.generatedImportReference;
44651
+ const specifier = getIdentifierGeneratedImportReference(nodeIn);
44652
+ if (specifier) {
44653
+ return specifier;
44627
44654
}
44628
44655
const node = getParseTreeNode(nodeIn, isIdentifier);
44629
44656
if (node) {
@@ -46894,7 +46921,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
46894
46921
46895
46922
function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean {
46896
46923
if (name.kind === SyntaxKind.Identifier) {
46897
- if (name.originalKeywordKind === SyntaxKind.LetKeyword ) {
46924
+ if (name.escapedText === "let" ) {
46898
46925
return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
46899
46926
}
46900
46927
}
0 commit comments