@@ -272,6 +272,8 @@ import {
272272 getFirstIdentifier,
273273 getFunctionFlags,
274274 getHostSignatureFromJSDoc,
275+ getIdentifierGeneratedImportReference,
276+ getIdentifierTypeArguments,
275277 getImmediatelyInvokedFunctionExpression,
276278 getInitializerOfBinaryExpression,
277279 getInterfaceBaseTypeNodes,
@@ -375,6 +377,7 @@ import {
375377 hasSyntacticModifiers,
376378 HeritageClause,
377379 Identifier,
380+ identifierToKeywordKind,
378381 IdentifierTypePredicate,
379382 idText,
380383 IfStatement,
@@ -890,11 +893,13 @@ import {
890893 ReverseMappedType,
891894 sameMap,
892895 SatisfiesExpression,
896+ scanTokenAtPosition,
893897 ScriptKind,
894898 ScriptTarget,
895899 SetAccessorDeclaration,
896900 setCommentRange,
897901 setEmitFlags,
902+ setIdentifierTypeArguments,
898903 setNodeFlags,
899904 setOriginalNode,
900905 setParent,
@@ -6794,12 +6799,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
67946799 let qualifier = root.qualifier;
67956800 if (qualifier) {
67966801 if (isIdentifier(qualifier)) {
6797- qualifier = factory.updateIdentifier(qualifier, typeArguments);
6802+ if (typeArguments !== getIdentifierTypeArguments(qualifier)) {
6803+ qualifier = setIdentifierTypeArguments(factory.cloneNode(qualifier), typeArguments);
6804+ }
67986805 }
67996806 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+ }
68036812 }
68046813 }
68056814 typeArguments = ref.typeArguments;
@@ -6821,12 +6830,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
68216830 let typeArguments = root.typeArguments;
68226831 let typeName = root.typeName;
68236832 if (isIdentifier(typeName)) {
6824- typeName = factory.updateIdentifier(typeName, typeArguments);
6833+ if (typeArguments !== getIdentifierTypeArguments(typeName)) {
6834+ typeName = setIdentifierTypeArguments(factory.cloneNode(typeName), typeArguments);
6835+ }
68256836 }
68266837 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+ }
68306843 }
68316844 typeArguments = ref.typeArguments;
68326845 // then move qualifiers
@@ -7544,7 +7557,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
75447557 if (!nonRootParts || isEntityName(nonRootParts)) {
75457558 if (nonRootParts) {
75467559 const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
7547- lastId. typeArguments = undefined;
7560+ setIdentifierTypeArguments( lastId, /* typeArguments*/ undefined) ;
75487561 }
75497562 return factory.createImportTypeNode(lit, assertion, nonRootParts as EntityName, typeParameterNodes as readonly TypeNode[], isTypeOf);
75507563 }
@@ -7564,8 +7577,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
75647577 }
75657578 else {
75667579 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) ;
75697582 return factory.createTypeReferenceNode(entityName, lastTypeArgs as NodeArray<TypeNode>);
75707583 }
75717584
@@ -7619,7 +7632,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
76197632 }
76207633 }
76217634
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));
76237637 identifier.symbol = symbol;
76247638
76257639 if (index > stopper) {
@@ -7664,7 +7678,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
76647678 text = `${rawtext}_${i}`;
76657679 }
76667680 if (text !== rawtext) {
7667- result = factory.createIdentifier(text, result.typeArguments);
7681+ const typeArguments = getIdentifierTypeArguments(result);
7682+ result = factory.createIdentifier(text);
7683+ setIdentifierTypeArguments(result, typeArguments);
76687684 }
76697685 // avoiding iterations of the above loop turns out to be worth it when `i` starts to get large, so we cache the max
76707686 // `i` we've used thus far, to save work later
@@ -7699,7 +7715,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
76997715 context.flags ^= NodeBuilderFlags.InInitialEntityName;
77007716 }
77017717
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));
77037720 identifier.symbol = symbol;
77047721
77057722 return index > 0 ? factory.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
@@ -7728,7 +7745,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
77287745 return factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context));
77297746 }
77307747 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));
77327750 identifier.symbol = symbol;
77337751
77347752 return index > 0 ? factory.createPropertyAccessExpression(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier;
@@ -7746,8 +7764,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
77467764 expression = factory.createNumericLiteral(+symbolName);
77477765 }
77487766 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;
77517771 }
77527772 return factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression);
77537773 }
@@ -23215,15 +23235,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2321523235 break;
2321623236 case SyntaxKind.Parameter:
2321723237 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+ }
2322723249 }
2322823250 diagnostic = (declaration as ParameterDeclaration).dotDotDotToken ?
2322923251 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 :
@@ -23465,6 +23487,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2346523487 type.flags & TypeFlags.Conditional && (getTrueTypeFromConditionalType(type as ConditionalType) === typeParameter || getFalseTypeFromConditionalType(type as ConditionalType) === typeParameter));
2346623488 }
2346723489
23490+ function isTypeParameterAtTopLevelInReturnType(signature: Signature, typeParameter: TypeParameter) {
23491+ const typePredicate = getTypePredicateOfSignature(signature);
23492+ return typePredicate ? !!typePredicate.type && isTypeParameterAtTopLevel(typePredicate.type, typeParameter) :
23493+ isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), typeParameter);
23494+ }
23495+
2346823496 /** Create an object with properties named in the string literal type. Every property has type `any` */
2346923497 function createEmptyObjectTypeFromStringLiteral(type: Type) {
2347023498 const members = createSymbolTable();
@@ -24573,7 +24601,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2457324601 // the type parameter was fixed during inference or does not occur at top-level in the return type.
2457424602 const primitiveConstraint = hasPrimitiveConstraint(inference.typeParameter) || isConstTypeVariable(inference.typeParameter);
2457524603 const widenLiteralTypes = !primitiveConstraint && inference.topLevel &&
24576- (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature( signature) , inference.typeParameter));
24604+ (inference.isFixed || !isTypeParameterAtTopLevelInReturnType( signature, inference.typeParameter));
2457724605 const baseCandidates = primitiveConstraint ? sameMap(candidates, getRegularTypeOfLiteralType) :
2457824606 widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) :
2457924607 candidates;
@@ -37477,8 +37505,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3747737505
3747837506 function checkTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments) {
3747937507 checkGrammarTypeArguments(node, node.typeArguments);
37480- if (node.kind === SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !isInJSFile(node) && !isInJSDoc(node)) {
37481- 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+ }
3748237514 }
3748337515 forEach(node.typeArguments, checkSourceElement);
3748437516 const type = getTypeFromTypeReference(node);
@@ -44616,8 +44648,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4461644648 // When resolved as an expression identifier, if the given node references an import, return the declaration of
4461744649 // that import. Otherwise, return undefined.
4461844650 function getReferencedImportDeclaration(nodeIn: Identifier): Declaration | undefined {
44619- if (nodeIn.generatedImportReference) {
44620- return nodeIn.generatedImportReference;
44651+ const specifier = getIdentifierGeneratedImportReference(nodeIn);
44652+ if (specifier) {
44653+ return specifier;
4462144654 }
4462244655 const node = getParseTreeNode(nodeIn, isIdentifier);
4462344656 if (node) {
@@ -46888,7 +46921,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4688846921
4688946922 function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean {
4689046923 if (name.kind === SyntaxKind.Identifier) {
46891- if (name.originalKeywordKind === SyntaxKind.LetKeyword ) {
46924+ if (name.escapedText === "let" ) {
4689246925 return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
4689346926 }
4689446927 }
0 commit comments