diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f18a0b2a32a23..b32f9fe61d89e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -447,6 +447,7 @@ import { InterfaceDeclaration, InterfaceType, InterfaceTypeWithDeclaredMembers, + InternalNodeBuilderFlags, InternalSymbolName, IntersectionFlags, IntersectionType, @@ -5911,6 +5912,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags: SymbolFormatFlags = SymbolFormatFlags.AllowAnyNodeKind, writer?: EmitTextWriter): string { let nodeFlags = NodeBuilderFlags.IgnoreErrors; + let internalNodeFlags = InternalNodeBuilderFlags.None; if (flags & SymbolFormatFlags.UseOnlyExternalAliasing) { nodeFlags |= NodeBuilderFlags.UseOnlyExternalAliasing; } @@ -5921,16 +5923,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { nodeFlags |= NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; } if (flags & SymbolFormatFlags.DoNotIncludeSymbolChain) { - nodeFlags |= NodeBuilderFlags.DoNotIncludeSymbolChain; + internalNodeFlags |= InternalNodeBuilderFlags.DoNotIncludeSymbolChain; } if (flags & SymbolFormatFlags.WriteComputedProps) { - nodeFlags |= NodeBuilderFlags.WriteComputedProps; + internalNodeFlags |= InternalNodeBuilderFlags.WriteComputedProps; } const builder = flags & SymbolFormatFlags.AllowAnyNodeKind ? nodeBuilder.symbolToNode : nodeBuilder.symbolToEntityName; return writer ? symbolToStringWorker(writer).getText() : usingSingleLineStringWriter(symbolToStringWorker); function symbolToStringWorker(writer: EmitTextWriter) { - const entity = builder(symbol, meaning!, enclosingDeclaration, nodeFlags)!; // TODO: GH#18217 + const entity = builder(symbol, meaning!, enclosingDeclaration, nodeFlags, internalNodeFlags)!; // TODO: GH#18217 // add neverAsciiEscape for GH#39027 const printer = enclosingDeclaration?.kind === SyntaxKind.SourceFile ? createPrinterWithRemoveCommentsNeverAsciiEscape() @@ -5962,7 +5964,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function typeToString(type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer: EmitTextWriter = createTextWriter("")): string { const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation; - const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : 0)); + const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : NodeBuilderFlags.None), /*internalFlags*/ undefined); if (typeNode === undefined) return Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. @@ -6013,20 +6015,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function createNodeBuilder() { return { - typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)), - typePredicateToTypePredicateNode: (typePredicate: TypePredicate, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typePredicateToTypePredicateNodeHelper(typePredicate, context)), - expressionOrTypeToTypeNode: (expr: Expression | JsxAttributeValue | undefined, type: Type, addUndefined?: boolean, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => expressionOrTypeToTypeNode(context, expr, type, addUndefined)), - serializeTypeForDeclaration: (declaration: Declaration, type: Type, symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => serializeTypeForDeclaration(context, declaration, type, symbol)), - serializeReturnTypeForSignature: (signature: Signature, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => serializeReturnTypeForSignature(context, signature)), - indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, context, /*typeNode*/ undefined)), - signatureToSignatureDeclaration: (signature: Signature, kind: SignatureDeclaration["kind"], enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => signatureToSignatureDeclarationHelper(signature, kind, context)), - symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false)), - symbolToExpression: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToExpression(symbol, context, meaning)), - symbolToTypeParameterDeclarations: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeParametersToTypeParameterDeclarations(symbol, context)), - symbolToParameterDeclaration: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToParameterDeclaration(symbol, context)), - typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeParameterToDeclaration(parameter, context)), - symbolTableToDeclarationStatements: (symbolTable: SymbolTable, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context)), - symbolToNode: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToNode(symbol, context, meaning)), + typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typeToTypeNodeHelper(type, context)), + typePredicateToTypePredicateNode: (typePredicate: TypePredicate, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typePredicateToTypePredicateNodeHelper(typePredicate, context)), + expressionOrTypeToTypeNode: (expr: Expression | JsxAttributeValue | undefined, type: Type, addUndefined?: boolean, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => expressionOrTypeToTypeNode(context, expr, type, addUndefined)), + serializeTypeForDeclaration: (declaration: Declaration, type: Type, symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => serializeTypeForDeclaration(context, declaration, type, symbol)), + serializeReturnTypeForSignature: (signature: Signature, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => serializeReturnTypeForSignature(context, signature)), + indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, context, /*typeNode*/ undefined)), + signatureToSignatureDeclaration: (signature: Signature, kind: SignatureDeclaration["kind"], enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => signatureToSignatureDeclarationHelper(signature, kind, context)), + symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false)), + symbolToExpression: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToExpression(symbol, context, meaning)), + symbolToTypeParameterDeclarations: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typeParametersToTypeParameterDeclarations(symbol, context)), + symbolToParameterDeclaration: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToParameterDeclaration(symbol, context)), + typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => typeParameterToDeclaration(parameter, context)), + symbolTableToDeclarationStatements: (symbolTable: SymbolTable, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context)), + symbolToNode: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, internalFlags, tracker, context => symbolToNode(symbol, context, meaning)), }; function getTypeFromTypeNode(context: NodeBuilderContext, node: TypeNode, noMappedTypes?: false): Type; @@ -6066,13 +6068,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * Same as expressionOrTypeToTypeNodeHelper, but also checks if the expression can be syntactically typed. */ function expressionOrTypeToTypeNode(context: NodeBuilderContext, expr: Expression | JsxAttributeValue | undefined, type: Type, addUndefined?: boolean) { - const oldFlags = context.flags; - if (expr && !(context.flags & NodeBuilderFlags.NoSyntacticPrinter)) { + const restoreFlags = saveRestoreFlags(context); + if (expr && !(context.internalFlags & InternalNodeBuilderFlags.NoSyntacticPrinter)) { syntacticNodeBuilder.serializeTypeOfExpression(expr, context, addUndefined); } - context.flags |= NodeBuilderFlags.NoSyntacticPrinter; + context.internalFlags |= InternalNodeBuilderFlags.NoSyntacticPrinter; const result = expressionOrTypeToTypeNodeHelper(context, expr, type, addUndefined); - context.flags = oldFlags; + restoreFlags(); return result; } function expressionOrTypeToTypeNodeHelper(context: NodeBuilderContext, expr: Expression | JsxAttributeValue | undefined, type: Type, addUndefined?: boolean) { @@ -6140,7 +6142,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function symbolToNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags) { - if (context.flags & NodeBuilderFlags.WriteComputedProps) { + if (context.internalFlags & InternalNodeBuilderFlags.WriteComputedProps) { if (symbol.valueDeclaration) { const name = getNameOfDeclaration(symbol.valueDeclaration); if (name && isComputedPropertyName(name)) return name; @@ -6154,14 +6156,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return symbolToExpression(symbol, context, meaning); } - function withContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker: SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined { + function withContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags: InternalNodeBuilderFlags | undefined, tracker: SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined { const moduleResolverHost = tracker?.trackSymbol ? tracker.moduleResolverHost : - flags! & NodeBuilderFlags.DoNotIncludeSymbolChain ? createBasicNodeBuilderModuleSpecifierResolutionHost(host) : + (internalFlags || InternalNodeBuilderFlags.None) & InternalNodeBuilderFlags.DoNotIncludeSymbolChain ? createBasicNodeBuilderModuleSpecifierResolutionHost(host) : undefined; const context: NodeBuilderContext = { enclosingDeclaration, enclosingFile: enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration), flags: flags || NodeBuilderFlags.None, + internalFlags: internalFlags || InternalNodeBuilderFlags.None, tracker: undefined!, encounteredError: false, reportedDiagnostic: false, @@ -6192,15 +6195,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return context.encounteredError ? undefined : resultingNode; } + function saveRestoreFlags(context: NodeBuilderContext) { + const flags = context.flags; + const internalFlags = context.internalFlags; + + return restore; + + function restore() { + context.flags = flags; + context.internalFlags = internalFlags; + } + } + function checkTruncationLength(context: NodeBuilderContext): boolean { if (context.truncating) return context.truncating; return context.truncating = context.approximateLength > ((context.flags & NodeBuilderFlags.NoTruncation) ? noTruncationMaximumTruncationLength : defaultMaximumTruncationLength); } function typeToTypeNodeHelper(type: Type, context: NodeBuilderContext): TypeNode { - const savedFlags = context.flags; + const restoreFlags = saveRestoreFlags(context); const typeNode = typeToTypeNodeWorker(type, context); - context.flags = savedFlags; + restoreFlags(); return typeNode; } @@ -6677,7 +6692,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const links = context.enclosingDeclaration && getNodeLinks(context.enclosingDeclaration); - const key = `${getTypeId(type)}|${context.flags}`; + const key = `${getTypeId(type)}|${context.flags}|${context.internalFlags}`; if (links) { links.serializedTypes ||= new Map(); } @@ -6798,10 +6813,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return typeToTypeNodeHelper(getIntersectionType(types), context); } - const savedFlags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags |= NodeBuilderFlags.InObjectTypeLiteral; const members = createTypeNodesFromResolvedType(resolved); - context.flags = savedFlags; + restoreFlags(); const typeLiteralNode = factory.createTypeLiteralNode(members); context.approximateLength += 2; setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine); @@ -6882,10 +6897,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // the default outer type arguments), we don't show the group. if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { const typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context); - const flags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags |= NodeBuilderFlags.ForbidIndexedAccessSymbolReferences; const ref = symbolToTypeNode(parent, context, SymbolFlags.Type, typeArgumentSlice) as TypeReferenceNode | ImportTypeNode; - context.flags = flags; + restoreFlags(); resultType = !resultType ? ref : appendReferenceToType(resultType, ref as TypeReferenceNode); } } @@ -6925,10 +6940,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context); } - const flags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags |= NodeBuilderFlags.ForbidIndexedAccessSymbolReferences; const finalRef = symbolToTypeNode(type.symbol, context, SymbolFlags.Type, typeArgumentNodes); - context.flags = flags; + restoreFlags(); return !resultType ? finalRef : appendReferenceToType(resultType, finalRef as TypeReferenceNode); } } @@ -7255,7 +7270,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // once while referring to different types. If so, regenerate the // type node for each entry by that name with the // `UseFullyQualifiedType` flag enabled. - const saveContextFlags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags |= NodeBuilderFlags.UseFullyQualifiedType; seenNames.forEach(types => { if (!arrayIsHomogeneous(types, ([a], [b]) => typesAreSameReference(a, b))) { @@ -7264,7 +7279,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } }); - context.flags = saveContextFlags; + restoreFlags(); } return result; @@ -7324,7 +7339,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, context)); } - const flags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags &= ~NodeBuilderFlags.SuppressAnyReturnType; // SuppressAnyReturnType should only apply to the signature `return` position // If the expanded parameter list had a variadic in a non-trailing position, don't expand it const parameters = (some(expandedParams, p => p !== expandedParams[expandedParams.length - 1] && !!(getCheckFlags(p) & CheckFlags.RestParameter)) ? signature.parameters : expandedParams).map(parameter => symbolToParameterDeclaration(parameter, context, kind === SyntaxKind.Constructor)); @@ -7332,7 +7347,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (thisParameter) { parameters.unshift(thisParameter); } - context.flags = flags; + restoreFlags(); const returnTypeNode = serializeReturnTypeForSignature(context, signature); @@ -7571,13 +7586,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration { - const savedContextFlags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic const modifiers = factory.createModifiersFromModifierFlags(getTypeParameterModifiers(type)); const name = typeParameterToName(type, context); const defaultParameter = getDefaultFromTypeParameter(type); const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context); - context.flags = savedContextFlags; + restoreFlags(); return factory.createTypeParameterDeclaration(modifiers, name, constraintNode, defaultParameterNode); } @@ -7686,7 +7701,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. let chain: Symbol[]; const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; - if (!isTypeParameter && (context.enclosingDeclaration || context.flags & NodeBuilderFlags.UseFullyQualifiedType) && !(context.flags & NodeBuilderFlags.DoNotIncludeSymbolChain)) { + if (!isTypeParameter && (context.enclosingDeclaration || context.flags & NodeBuilderFlags.UseFullyQualifiedType) && !(context.internalFlags & InternalNodeBuilderFlags.DoNotIncludeSymbolChain)) { chain = Debug.checkDefined(getSymbolChain(symbol, meaning, /*endOfChain*/ true)); Debug.assert(chain && chain.length > 0); } @@ -8298,12 +8313,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function serializeTypeForDeclaration(context: NodeBuilderContext, declaration: Declaration | undefined, type: Type, symbol: Symbol) { const addUndefinedForParameter = declaration && (isParameter(declaration) || isJSDocParameterTag(declaration)) && requiresAddingImplicitUndefined(declaration); const enclosingDeclaration = context.enclosingDeclaration; - const oldFlags = context.flags; - if (declaration && hasInferredType(declaration) && !(context.flags & NodeBuilderFlags.NoSyntacticPrinter)) { + const restoreFlags = saveRestoreFlags(context); + if (declaration && hasInferredType(declaration) && !(context.internalFlags & InternalNodeBuilderFlags.NoSyntacticPrinter)) { syntacticNodeBuilder.serializeTypeOfDeclaration(declaration, context); } - context.flags |= NodeBuilderFlags.NoSyntacticPrinter; - if (enclosingDeclaration && (!isErrorType(type) || (context.flags & NodeBuilderFlags.AllowUnresolvedNames))) { + context.internalFlags |= InternalNodeBuilderFlags.NoSyntacticPrinter; + if (enclosingDeclaration && (!isErrorType(type) || (context.internalFlags & InternalNodeBuilderFlags.AllowUnresolvedNames))) { const declWithExistingAnnotation = declaration && getNonlocalEffectiveTypeAnnotationNode(declaration) ? declaration : getDeclarationWithTypeAnnotation(symbol); @@ -8314,7 +8329,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const addUndefined = addUndefinedForParameter || !!(symbol.flags & SymbolFlags.Property && symbol.flags & SymbolFlags.Optional && isOptionalDeclaration(declWithExistingAnnotation) && (symbol as MappedSymbol).links?.mappedType && containsNonMissingUndefinedType(type)); const result = !isTypePredicateNode(existing) && tryReuseExistingTypeNode(context, existing, type, declWithExistingAnnotation, addUndefined); if (result) { - context.flags = oldFlags; + restoreFlags(); return result; } } @@ -8330,7 +8345,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const expr = decl && isDeclarationWithPossibleInnerTypeNodeReuse(decl) ? getPossibleTypeNodeReuseExpression(decl) : undefined; const result = expressionOrTypeToTypeNode(context, expr, type, addUndefinedForParameter); - context.flags = oldFlags; + restoreFlags(); return result; } @@ -8346,28 +8361,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function serializeReturnTypeForSignature(context: NodeBuilderContext, signature: Signature) { const suppressAny = context.flags & NodeBuilderFlags.SuppressAnyReturnType; - const flags = context.flags; + const restoreFlags = saveRestoreFlags(context); if (suppressAny) context.flags &= ~NodeBuilderFlags.SuppressAnyReturnType; // suppress only toplevel `any`s let returnTypeNode: TypeNode | undefined; const returnType = getReturnTypeOfSignature(signature); if (returnType && !(suppressAny && isTypeAny(returnType))) { - if (signature.declaration && !(context.flags & NodeBuilderFlags.NoSyntacticPrinter)) { + if (signature.declaration && !(context.internalFlags & InternalNodeBuilderFlags.NoSyntacticPrinter)) { syntacticNodeBuilder.serializeReturnTypeForSignature(signature.declaration, context); } - context.flags |= NodeBuilderFlags.NoSyntacticPrinter; + context.internalFlags |= InternalNodeBuilderFlags.NoSyntacticPrinter; returnTypeNode = serializeReturnTypeForSignatureWorker(context, signature); } else if (!suppressAny) { returnTypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } - context.flags = flags; + restoreFlags(); return returnTypeNode; } function serializeReturnTypeForSignatureWorker(context: NodeBuilderContext, signature: Signature) { const typePredicate = getTypePredicateOfSignature(signature); const type = getReturnTypeOfSignature(signature); - if (context.enclosingDeclaration && (!isErrorType(type) || (context.flags & NodeBuilderFlags.AllowUnresolvedNames)) && signature.declaration && !nodeIsSynthesized(signature.declaration)) { + if (context.enclosingDeclaration && (!isErrorType(type) || (context.internalFlags & InternalNodeBuilderFlags.AllowUnresolvedNames)) && signature.declaration && !nodeIsSynthesized(signature.declaration)) { const annotation = getNonlocalEffectiveReturnTypeAnnotationNode(signature.declaration); if (annotation) { const result = tryReuseExistingTypeNode(context, annotation, type, context.enclosingDeclaration); @@ -8883,7 +8898,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!hasDynamicName(node)) { return visitEachChild(node, visitExistingNodeTreeSymbols); } - if (!(context.flags & NodeBuilderFlags.AllowUnresolvedNames && isEntityNameExpression(node.name.expression) && checkComputedPropertyName(node.name).flags & TypeFlags.Any)) { + if (!(context.internalFlags & InternalNodeBuilderFlags.AllowUnresolvedNames && isEntityNameExpression(node.name.expression) && checkComputedPropertyName(node.name).flags & TypeFlags.Any)) { return undefined; } } @@ -9615,7 +9630,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const typeParamDecls = map(typeParams, p => typeParameterToDeclaration(p, context)); const jsdocAliasDecl = symbol.declarations?.find(isJSDocTypeAlias); const commentText = getTextOfJSDocComment(jsdocAliasDecl ? jsdocAliasDecl.comment || jsdocAliasDecl.parent.comment : undefined); - const oldFlags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags |= NodeBuilderFlags.InTypeAlias; const oldEnclosingDecl = context.enclosingDeclaration; context.enclosingDeclaration = jsdocAliasDecl; @@ -9630,7 +9645,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ), modifierFlags, ); - context.flags = oldFlags; + restoreFlags(); context.enclosingDeclaration = oldEnclosingDecl; } @@ -10643,10 +10658,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getNameCandidateWorker(symbol: Symbol, localName: string) { if (localName === InternalSymbolName.Default || localName === InternalSymbolName.Class || localName === InternalSymbolName.Function) { - const flags = context.flags; + const restoreFlags = saveRestoreFlags(context); context.flags |= NodeBuilderFlags.InInitialEntityName; const nameCandidate = getNameOfSymbolAsWritten(symbol, context); - context.flags = flags; + restoreFlags(); localName = nameCandidate.length > 0 && isSingleOrDoubleQuote(nameCandidate.charCodeAt(0)) ? stripQuotes(nameCandidate) : nameCandidate; } if (localName === InternalSymbolName.Default) { @@ -49751,7 +49766,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function createTypeOfDeclaration(declarationIn: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker) { + function createTypeOfDeclaration(declarationIn: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) { const declaration = getParseTreeNode(declarationIn, isVariableLikeOrAccessor); if (!declaration) { return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; @@ -49762,7 +49777,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ? getWidenedLiteralType(getTypeOfSymbol(symbol)) : errorType; - return nodeBuilder.serializeTypeForDeclaration(declaration, type, symbol, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); + return nodeBuilder.serializeTypeForDeclaration(declaration, type, symbol, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, internalFlags, tracker); } type DeclarationWithPotentialInnerNodeReuse = @@ -49828,21 +49843,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return candidateExpr; } - function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker) { + function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) { const signatureDeclaration = getParseTreeNode(signatureDeclarationIn, isFunctionLike); if (!signatureDeclaration) { return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; } - return nodeBuilder.serializeReturnTypeForSignature(getSignatureFromDeclaration(signatureDeclaration), enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); + return nodeBuilder.serializeReturnTypeForSignature(getSignatureFromDeclaration(signatureDeclaration), enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, internalFlags, tracker); } - function createTypeOfExpression(exprIn: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker) { + function createTypeOfExpression(exprIn: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) { const expr = getParseTreeNode(exprIn, isExpression); if (!expr) { return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; } const type = getWidenedType(getRegularTypeOfExpression(expr)); - return nodeBuilder.expressionOrTypeToTypeNode(expr, type, /*addUndefined*/ undefined, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); + return nodeBuilder.expressionOrTypeToTypeNode(expr, type, /*addUndefined*/ undefined, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, internalFlags, tracker); } function hasGlobalName(name: string): boolean { @@ -49950,7 +49965,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function literalTypeToNode(type: FreshableType, enclosing: Node, tracker: SymbolTracker): Expression { - const enumResult = type.flags & TypeFlags.EnumLike ? nodeBuilder.symbolToExpression(type.symbol, SymbolFlags.Value, enclosing, /*flags*/ undefined, tracker) + const enumResult = type.flags & TypeFlags.EnumLike ? nodeBuilder.symbolToExpression(type.symbol, SymbolFlags.Value, enclosing, /*flags*/ undefined, /*internalFlags*/ undefined, tracker) : type === trueType ? factory.createTrue() : type === falseType && factory.createFalse(); if (enumResult) return enumResult; const literalValue = (type as LiteralType).value; @@ -50090,15 +50105,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const parseDecl = getParseTreeNode(decl); return !!parseNode && !!parseDecl && (isVariableDeclaration(parseDecl) || isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl); }, - getDeclarationStatementsForSourceFile: (node, flags, tracker) => { + getDeclarationStatementsForSourceFile: (node, flags, internalFlags, tracker) => { const n = getParseTreeNode(node) as SourceFile; Debug.assert(n && n.kind === SyntaxKind.SourceFile, "Non-sourcefile node passed into getDeclarationsForSourceFile"); const sym = getSymbolOfDeclaration(node); if (!sym) { - return !node.locals ? [] : nodeBuilder.symbolTableToDeclarationStatements(node.locals, node, flags, tracker); + return !node.locals ? [] : nodeBuilder.symbolTableToDeclarationStatements(node.locals, node, flags, internalFlags, tracker); } resolveExternalModuleSymbol(sym); // ensures cjs export assignment is setup - return !sym.exports ? [] : nodeBuilder.symbolTableToDeclarationStatements(sym.exports, node, flags, tracker); + return !sym.exports ? [] : nodeBuilder.symbolTableToDeclarationStatements(sym.exports, node, flags, internalFlags, tracker); }, isImportRequiredByAugmentation, isDefinitelyReferenceToGlobalSymbolObject, @@ -52425,6 +52440,7 @@ interface NodeBuilderContext { */ enclosingFile: SourceFile | undefined; flags: NodeBuilderFlags; + internalFlags: InternalNodeBuilderFlags; tracker: SymbolTrackerImpl; // State diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 166431a745069..536e0cf5d9c22 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -87,6 +87,7 @@ import { ImportTypeNode, IndexSignatureDeclaration, InterfaceDeclaration, + InternalNodeBuilderFlags, isAmbientModule, isArray, isArrayBindingElement, @@ -239,10 +240,11 @@ const declarationEmitNodeBuilderFlags = NodeBuilderFlags.MultilineObjectLiterals NodeBuilderFlags.UseTypeOfFunction | NodeBuilderFlags.UseStructuralFallback | NodeBuilderFlags.AllowEmptyTuple | - NodeBuilderFlags.AllowUnresolvedNames | NodeBuilderFlags.GenerateNamesForShadowedTypeParams | NodeBuilderFlags.NoTruncation; +const declarationEmitInternalNodeBuilderFlags = InternalNodeBuilderFlags.AllowUnresolvedNames; + /** * Transforms a ts file into a .d.ts file * This process requires type information, which is retrieved through the emit resolver. Because of this, @@ -429,7 +431,7 @@ export function transformDeclarations(context: TransformationContext) { : Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit, errorNode: s.errorNode || sourceFile, })); - const result = resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, symbolTracker); + const result = resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags, symbolTracker); getSymbolAccessibilityDiagnostic = oldDiag; return result; } @@ -696,7 +698,7 @@ export function transformDeclarations(context: TransformationContext) { case SyntaxKind.PropertyDeclaration: case SyntaxKind.BindingElement: case SyntaxKind.VariableDeclaration: - typeNode = resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker); + typeNode = resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags, symbolTracker); break; case SyntaxKind.FunctionDeclaration: case SyntaxKind.ConstructSignature: @@ -704,7 +706,7 @@ export function transformDeclarations(context: TransformationContext) { case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.CallSignature: - typeNode = resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker); + typeNode = resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags, symbolTracker); break; default: Debug.assertNever(node); @@ -1329,7 +1331,7 @@ export function transformDeclarations(context: TransformationContext) { errorNode: input, }); errorFallbackNode = input; - const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); + const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); errorFallbackNode = undefined; const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const)); @@ -1471,7 +1473,7 @@ export function transformDeclarations(context: TransformationContext) { return undefined; // unique symbol or non-identifier name - omit, since there's no syntax that can preserve it } getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration); - const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags | NodeBuilderFlags.NoSyntacticPrinter, symbolTracker); + const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags | InternalNodeBuilderFlags.NoSyntacticPrinter, symbolTracker); getSymbolAccessibilityDiagnostic = oldDiag; const isNonContextualKeywordName = isStringANonContextualKeyword(nameStr); const name = isNonContextualKeywordName ? factory.getGeneratedNameForNode(p.valueDeclaration) : factory.createIdentifier(nameStr); @@ -1666,7 +1668,7 @@ export function transformDeclarations(context: TransformationContext) { errorNode: extendsClause, typeName: input.name, }); - const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(extendsClause.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); + const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(extendsClause.expression, input, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const)); const heritageClauses = factory.createNodeArray(map(input.heritageClauses, clause => { if (clause.token === SyntaxKind.ExtendsKeyword) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 564fa64e1294c..eab2492d3c91a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5073,14 +5073,14 @@ export interface TypeChecker { // TODO: GH#18217 `xToDeclaration` calls are frequently asserted as defined. /** Note that the resulting nodes cannot be checked. */ typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined; - /** @internal */ typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): TypeNode | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - /** @internal */ typePredicateToTypePredicateNode(typePredicate: TypePredicate, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): TypePredicateNode | undefined; + /** @internal */ typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags?: InternalNodeBuilderFlags | undefined, tracker?: SymbolTracker): TypeNode | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + /** @internal */ typePredicateToTypePredicateNode(typePredicate: TypePredicate, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags?: InternalNodeBuilderFlags | undefined, tracker?: SymbolTracker): TypePredicateNode | undefined; /** Note that the resulting nodes cannot be checked. */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): SignatureDeclaration & { typeArguments?: NodeArray; } | undefined; - /** @internal */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): SignatureDeclaration & { typeArguments?: NodeArray; } | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + /** @internal */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags?: InternalNodeBuilderFlags | undefined, tracker?: SymbolTracker): SignatureDeclaration & { typeArguments?: NodeArray; } | undefined; // eslint-disable-line @typescript-eslint/unified-signatures /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined; - /** @internal */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): IndexSignatureDeclaration | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + /** @internal */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags?: InternalNodeBuilderFlags | undefined, tracker?: SymbolTracker): IndexSignatureDeclaration | undefined; // eslint-disable-line @typescript-eslint/unified-signatures /** Note that the resulting nodes cannot be checked. */ symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): EntityName | undefined; /** Note that the resulting nodes cannot be checked. */ @@ -5090,7 +5090,7 @@ export interface TypeChecker { * * @internal */ - symbolToNode(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): Node | undefined; + symbolToNode(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, internalFlags: InternalNodeBuilderFlags | undefined): Node | undefined; /** Note that the resulting nodes cannot be checked. */ symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeArray | undefined; /** Note that the resulting nodes cannot be checked. */ @@ -5459,12 +5459,9 @@ export const enum NodeBuilderFlags { AllowEmptyTuple = 1 << 19, AllowUniqueESSymbolType = 1 << 20, AllowEmptyIndexInfoType = 1 << 21, - /** @internal */ WriteComputedProps = 1 << 30, // { [E.A]: 1 } - /** @internal */ NoSyntacticPrinter = 1 << 31, // Errors (cont.) AllowNodeModulesRelativePaths = 1 << 26, - /** @internal */ DoNotIncludeSymbolChain = 1 << 27, // Skip looking up and printing an accessible symbol chain - /** @internal */ AllowUnresolvedNames = 1 << 32, + IgnoreErrors = AllowThisInObjectLiteral | AllowQualifiedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple | AllowEmptyIndexInfoType | AllowNodeModulesRelativePaths, @@ -5474,6 +5471,16 @@ export const enum NodeBuilderFlags { InInitialEntityName = 1 << 24, // Set when writing the LHS of an entity name or entity name expression } +/** @internal */ +// dprint-ignore +export const enum InternalNodeBuilderFlags { + None = 0, + WriteComputedProps = 1 << 0, // { [E.A]: 1 } + NoSyntacticPrinter = 1 << 1, + DoNotIncludeSymbolChain = 1 << 2, // Skip looking up and printing an accessible symbol chain + AllowUnresolvedNames = 1 << 3, +} + // Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment // dprint-ignore export const enum TypeFormatFlags { @@ -5810,9 +5817,9 @@ export interface EmitResolver { requiresAddingImplicitUndefined(node: ParameterDeclaration): boolean; isExpandoFunctionDeclaration(node: FunctionDeclaration | VariableDeclaration): boolean; getPropertiesOfContainerFunction(node: Declaration): Symbol[]; - createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression | ElementAccessExpression | BinaryExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; - createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; - createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; + createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression | ElementAccessExpression | BinaryExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; + createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; + createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker): Expression; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags | undefined, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult; isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; @@ -5829,7 +5836,7 @@ export interface EmitResolver { getJsxFactoryEntity(location?: Node): EntityName | undefined; getJsxFragmentFactoryEntity(location?: Node): EntityName | undefined; isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean; - getDeclarationStatementsForSourceFile(node: SourceFile, flags: NodeBuilderFlags, tracker: SymbolTracker): Statement[] | undefined; + getDeclarationStatementsForSourceFile(node: SourceFile, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): Statement[] | undefined; isImportRequiredByAugmentation(decl: ImportDeclaration): boolean; isDefinitelyReferenceToGlobalSymbolObject(node: Node): boolean; } diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index e09f8bd56a272..96bd527077d8e 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -279,7 +279,7 @@ export class TypeWriterWalker { } else { const typeFormatFlags = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType | ts.TypeFormatFlags.GenerateNamesForShadowedTypeParams; - let typeNode = this.checker.typeToTypeNode(type, node.parent, (typeFormatFlags & ts.TypeFormatFlags.NodeBuilderFlagsMask) | ts.NodeBuilderFlags.IgnoreErrors)!; + let typeNode = this.checker.typeToTypeNode(type, node.parent, (typeFormatFlags & ts.TypeFormatFlags.NodeBuilderFlagsMask) | ts.NodeBuilderFlags.IgnoreErrors, ts.InternalNodeBuilderFlags.AllowUnresolvedNames)!; if (ts.isIdentifier(node) && ts.isTypeAliasDeclaration(node.parent) && node.parent.name === node && ts.isIdentifier(typeNode) && ts.idText(typeNode) === ts.idText(node)) { // for a complex type alias `type T = ...`, showing "T : T" isn't very helpful for type tests. When the type produced is the same as // the name of the type alias, recreate the type string without reusing the alias name diff --git a/src/services/codefixes/fixAddMissingConstraint.ts b/src/services/codefixes/fixAddMissingConstraint.ts index fad9a8f003a5c..ba1e7aa0279c2 100644 --- a/src/services/codefixes/fixAddMissingConstraint.ts +++ b/src/services/codefixes/fixAddMissingConstraint.ts @@ -123,7 +123,7 @@ function addMissingConstraint(changes: textChanges.ChangeTracker, program: Progr const scriptTarget = getEmitScriptTarget(program.getCompilerOptions()); const tracker = getNoopSymbolTrackerWithResolver({ program, host }); const importAdder = createImportAdder(sourceFile, program, preferences, host); - const typeNode = typeToAutoImportableTypeNode(checker, importAdder, constraint, /*contextNode*/ undefined, scriptTarget, /*flags*/ undefined, tracker); + const typeNode = typeToAutoImportableTypeNode(checker, importAdder, constraint, /*contextNode*/ undefined, scriptTarget, /*flags*/ undefined, /*internalFlags*/ undefined, tracker); if (typeNode) { changes.replaceNode(sourceFile, declaration, factory.updateTypeParameterDeclaration(declaration, /*modifiers*/ undefined, declaration.name, typeNode, declaration.default)); importAdder.writeFixes(changes); diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 190fba39043c0..77bec1ed7f173 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -55,6 +55,7 @@ import { Identifier, idText, InterfaceDeclaration, + InternalNodeBuilderFlags, isCallExpression, isClassLike, isComputedPropertyName, @@ -493,11 +494,11 @@ function getTypeNode(checker: TypeChecker, node: ClassLikeDeclaration | Interfac const binaryExpression = token.parent.parent as BinaryExpression; const otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left; const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression))); - typeNode = checker.typeToTypeNode(widenedType, node, NodeBuilderFlags.NoTruncation); + typeNode = checker.typeToTypeNode(widenedType, node, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames); } else { const contextualType = checker.getContextualType(token.parent as Expression); - typeNode = contextualType ? checker.typeToTypeNode(contextualType, /*enclosingDeclaration*/ undefined, NodeBuilderFlags.NoTruncation) : undefined; + typeNode = contextualType ? checker.typeToTypeNode(contextualType, /*enclosingDeclaration*/ undefined, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames) : undefined; } return typeNode || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } @@ -775,7 +776,7 @@ function tryGetContainingMethodDeclaration(node: ClassLikeDeclaration | Interfac function createPropertyNameFromSymbol(symbol: Symbol, target: ScriptTarget, quotePreference: QuotePreference, checker: TypeChecker) { if (isTransientSymbol(symbol)) { - const prop = checker.symbolToNode(symbol, SymbolFlags.Value, /*enclosingDeclaration*/ undefined, NodeBuilderFlags.WriteComputedProps); + const prop = checker.symbolToNode(symbol, SymbolFlags.Value, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, InternalNodeBuilderFlags.WriteComputedProps); if (prop && isComputedPropertyName(prop)) return prop; } // We're using these nodes as property names in an object literal; no need to quote names when not needed. diff --git a/src/services/codefixes/fixAddMissingParam.ts b/src/services/codefixes/fixAddMissingParam.ts index c5ac4f25b2b09..65c9cf861586e 100644 --- a/src/services/codefixes/fixAddMissingParam.ts +++ b/src/services/codefixes/fixAddMissingParam.ts @@ -26,6 +26,7 @@ import { getNameOfDeclaration, getSourceFileOfNode, getTokenAtPosition, + InternalNodeBuilderFlags, isAccessExpression, isCallExpression, isIdentifier, @@ -221,7 +222,7 @@ function tryGetName(node: FunctionLikeDeclaration) { } function typeToTypeNode(checker: TypeChecker, type: Type, enclosingDeclaration: Node) { - return checker.typeToTypeNode(checker.getWidenedType(type), enclosingDeclaration, NodeBuilderFlags.NoTruncation) + return checker.typeToTypeNode(checker.getWidenedType(type), enclosingDeclaration, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames) ?? factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword); } diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index d5dacd51dc59d..a0dd5aa5e5899 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -108,7 +108,7 @@ function addMissingDeclarations( function createMissingIndexSignatureDeclaration(type: InterfaceType, kind: IndexKind): void { const indexInfoOfKind = checker.getIndexInfoOfType(type, kind); if (indexInfoOfKind) { - insertInterfaceMemberNode(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, classDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context))!); + insertInterfaceMemberNode(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, classDeclaration, /*flags*/ undefined, /*internalFlags*/ undefined, getNoopSymbolTrackerWithResolver(context))!); } } diff --git a/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts b/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts index db117935dea2d..9dae7f39679ea 100644 --- a/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts +++ b/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts @@ -36,6 +36,7 @@ import { hasInitializer, hasSyntacticModifier, Identifier, + InternalNodeBuilderFlags, isArrayBindingPattern, isArrayLiteralExpression, isAssertionExpression, @@ -160,8 +161,9 @@ const declarationEmitNodeBuilderFlags = NodeBuilderFlags.MultilineObjectLiterals | NodeBuilderFlags.UseStructuralFallback | NodeBuilderFlags.AllowEmptyTuple | NodeBuilderFlags.GenerateNamesForShadowedTypeParams - | NodeBuilderFlags.NoTruncation - | NodeBuilderFlags.WriteComputedProps; + | NodeBuilderFlags.NoTruncation; + +const declarationEmitInternalNodeBuilderFlags = InternalNodeBuilderFlags.WriteComputedProps; enum TypePrintMode { // Prints its fully spelled out type @@ -1096,7 +1098,7 @@ function withContext( function typeToTypeNode(type: Type, enclosingDeclaration: Node, flags = NodeBuilderFlags.None) { let isTruncated = false; - const result = typeToAutoImportableTypeNode(typeChecker, importAdder, type, enclosingDeclaration, scriptTarget, declarationEmitNodeBuilderFlags | flags, { + const result = typeToAutoImportableTypeNode(typeChecker, importAdder, type, enclosingDeclaration, scriptTarget, declarationEmitNodeBuilderFlags | flags, declarationEmitInternalNodeBuilderFlags, { moduleResolverHost: program, trackSymbol() { return true; @@ -1110,7 +1112,7 @@ function withContext( function typePredicateToTypeNode(typePredicate: TypePredicate, enclosingDeclaration: Node, flags = NodeBuilderFlags.None): TypeNode | undefined { let isTruncated = false; - const result = typePredicateToAutoImportableTypeNode(typeChecker, importAdder, typePredicate, enclosingDeclaration, scriptTarget, declarationEmitNodeBuilderFlags | flags, { + const result = typePredicateToAutoImportableTypeNode(typeChecker, importAdder, typePredicate, enclosingDeclaration, scriptTarget, declarationEmitNodeBuilderFlags | flags, declarationEmitInternalNodeBuilderFlags, { moduleResolverHost: program, trackSymbol() { return true; diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 0524080520582..f4a29c3751d12 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -41,6 +41,7 @@ import { hasAbstractModifier, Identifier, idText, + InternalNodeBuilderFlags, IntersectionType, isArrowFunction, isAutoAccessorPropertyDeclaration, @@ -222,7 +223,7 @@ export function addNewNodeForMemberSymbol( case SyntaxKind.PropertyDeclaration: let flags = NodeBuilderFlags.NoTruncation; flags |= quotePreference === QuotePreference.Single ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : 0; - let typeNode = checker.typeToTypeNode(type, enclosingDeclaration, flags, getNoopSymbolTrackerWithResolver(context)); + let typeNode = checker.typeToTypeNode(type, enclosingDeclaration, flags, InternalNodeBuilderFlags.AllowUnresolvedNames, getNoopSymbolTrackerWithResolver(context)); if (importAdder) { const importableReference = tryGetAutoImportableReferenceFromTypeNode(typeNode, scriptTarget); if (importableReference) { @@ -241,7 +242,7 @@ export function addNewNodeForMemberSymbol( case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: { Debug.assertIsDefined(declarations); - let typeNode = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context)); + let typeNode = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, /*internalFlags*/ undefined, getNoopSymbolTrackerWithResolver(context)); const allAccessors = getAllAccessorDeclarations(declarations, declaration as AccessorDeclaration); const orderedAccessors = allAccessors.secondAccessor ? [allAccessors.firstAccessor, allAccessors.secondAccessor] @@ -392,7 +393,7 @@ export function createSignatureDeclarationFromSignature( | NodeBuilderFlags.SuppressAnyReturnType | NodeBuilderFlags.AllowEmptyTuple | (quotePreference === QuotePreference.Single ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : NodeBuilderFlags.None); - const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags, getNoopSymbolTrackerWithResolver(context)) as ArrowFunction | FunctionExpression | MethodDeclaration | FunctionDeclaration; + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags, InternalNodeBuilderFlags.AllowUnresolvedNames, getNoopSymbolTrackerWithResolver(context)) as ArrowFunction | FunctionExpression | MethodDeclaration | FunctionDeclaration; if (!signatureDeclaration) { return undefined; } @@ -506,6 +507,7 @@ export function createSignatureDeclarationFromCallExpression( contextNode, scriptTarget, NodeBuilderFlags.NoTruncation, + InternalNodeBuilderFlags.AllowUnresolvedNames, tracker, ); @@ -519,7 +521,7 @@ export function createSignatureDeclarationFromCallExpression( const parameters = createDummyParameters(args.length, names, argumentTypeNodes, /*minArgumentCount*/ undefined, isJs); const type = isJs || contextualType === undefined ? undefined - : checker.typeToTypeNode(contextualType, contextNode, /*flags*/ undefined, tracker); + : checker.typeToTypeNode(contextualType, contextNode, /*flags*/ undefined, /*internalFlags*/ undefined, tracker); switch (kind) { case SyntaxKind.MethodDeclaration: @@ -589,8 +591,8 @@ function createTypeParameterName(index: number) { } /** @internal */ -export function typeToAutoImportableTypeNode(checker: TypeChecker, importAdder: ImportAdder, type: Type, contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined { - let typeNode = checker.typeToTypeNode(type, contextNode, flags, tracker); +export function typeToAutoImportableTypeNode(checker: TypeChecker, importAdder: ImportAdder, type: Type, contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined { + let typeNode = checker.typeToTypeNode(type, contextNode, flags, internalFlags, tracker); if (typeNode && isImportTypeNode(typeNode)) { const importableReference = tryGetAutoImportableReferenceFromTypeNode(typeNode, scriptTarget); if (importableReference) { @@ -604,8 +606,8 @@ export function typeToAutoImportableTypeNode(checker: TypeChecker, importAdder: } /** @internal */ -export function typePredicateToAutoImportableTypeNode(checker: TypeChecker, importAdder: ImportAdder, typePredicate: TypePredicate, contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined { - let typePredicateNode = checker.typePredicateToTypePredicateNode(typePredicate, contextNode, flags, tracker); +export function typePredicateToAutoImportableTypeNode(checker: TypeChecker, importAdder: ImportAdder, typePredicate: TypePredicate, contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined { + let typePredicateNode = checker.typePredicateToTypePredicateNode(typePredicate, contextNode, flags, internalFlags, tracker); if (typePredicateNode?.type && isImportTypeNode(typePredicateNode.type)) { const importableReference = tryGetAutoImportableReferenceFromTypeNode(typePredicateNode.type, scriptTarget); if (importableReference) { @@ -625,7 +627,7 @@ function typeContainsTypeParameter(type: Type) { return type.flags & TypeFlags.TypeParameter; } -function getArgumentTypesAndTypeParameters(checker: TypeChecker, importAdder: ImportAdder, instanceTypes: Type[], contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, tracker?: SymbolTracker) { +function getArgumentTypesAndTypeParameters(checker: TypeChecker, importAdder: ImportAdder, instanceTypes: Type[], contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker) { // Types to be used as the types of the parameters in the new function // E.g. from this source: // added("", 0) @@ -668,7 +670,7 @@ function getArgumentTypesAndTypeParameters(checker: TypeChecker, importAdder: Im // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" const widenedInstanceType = checker.getBaseTypeOfLiteralType(instanceType); - const argumentTypeNode = typeToAutoImportableTypeNode(checker, importAdder, widenedInstanceType, contextNode, scriptTarget, flags, tracker); + const argumentTypeNode = typeToAutoImportableTypeNode(checker, importAdder, widenedInstanceType, contextNode, scriptTarget, flags, internalFlags, tracker); if (!argumentTypeNode) { continue; } @@ -686,7 +688,7 @@ function getArgumentTypesAndTypeParameters(checker: TypeChecker, importAdder: Im // We instead want to output: // function added(value: T) { ... } const instanceTypeConstraint = instanceType.isTypeParameter() && instanceType.constraint && !isAnonymousObjectConstraintType(instanceType.constraint) - ? typeToAutoImportableTypeNode(checker, importAdder, instanceType.constraint, contextNode, scriptTarget, flags, tracker) + ? typeToAutoImportableTypeNode(checker, importAdder, instanceType.constraint, contextNode, scriptTarget, flags, internalFlags, tracker) : undefined; if (argumentTypeParameter) { @@ -795,7 +797,7 @@ function createMethodImplementingSignatures( function getReturnTypeFromSignatures(signatures: readonly Signature[], checker: TypeChecker, context: TypeConstructionContext, enclosingDeclaration: ClassLikeDeclaration): TypeNode | undefined { if (length(signatures)) { const type = checker.getUnionType(map(signatures, checker.getReturnTypeOfSignature)); - return checker.typeToTypeNode(type, enclosingDeclaration, NodeBuilderFlags.NoTruncation, getNoopSymbolTrackerWithResolver(context)); + return checker.typeToTypeNode(type, enclosingDeclaration, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames, getNoopSymbolTrackerWithResolver(context)); } } diff --git a/src/services/completions.ts b/src/services/completions.ts index 1300005c8b570..ee67c03331563 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -2324,7 +2324,7 @@ function createObjectLiteralMethod( // We don't support overloads in object literals. return undefined; } - const typeNode = checker.typeToTypeNode(effectiveType, enclosingDeclaration, builderFlags, codefix.getNoopSymbolTrackerWithResolver({ program, host })); + const typeNode = checker.typeToTypeNode(effectiveType, enclosingDeclaration, builderFlags, /*internalFlags*/ undefined, codefix.getNoopSymbolTrackerWithResolver({ program, host })); if (!typeNode || !isFunctionTypeNode(typeNode)) { return undefined; } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index d5ebc4e3c040d..4093074b9575a 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -61,6 +61,7 @@ import { hasEffectiveModifier, hasSyntacticModifier, Identifier, + InternalNodeBuilderFlags, isArray, isArrowFunction, isAssignmentExpression, @@ -1062,7 +1063,7 @@ function extractFunctionInScope( let type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" type = checker.getBaseTypeOfLiteralType(type); - typeNode = codefix.typeToAutoImportableTypeNode(checker, importAdder, type, scope, scriptTarget, NodeBuilderFlags.NoTruncation); + typeNode = codefix.typeToAutoImportableTypeNode(checker, importAdder, type, scope, scriptTarget, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames); } const paramDecl = factory.createParameterDeclaration( @@ -1096,7 +1097,7 @@ function extractFunctionInScope( // to avoid problems when there are literal types present if (isExpression(node) && !isJS) { const contextualType = checker.getContextualType(node); - returnType = checker.typeToTypeNode(contextualType!, scope, NodeBuilderFlags.NoTruncation); // TODO: GH#18217 + returnType = checker.typeToTypeNode(contextualType!, scope, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames); // TODO: GH#18217 } const { body, returnValueProperty } = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)); @@ -1138,6 +1139,7 @@ function extractFunctionInScope( checker.getTypeAtLocation(range.thisNode!), scope, NodeBuilderFlags.NoTruncation, + InternalNodeBuilderFlags.AllowUnresolvedNames, ), /*initializer*/ undefined, ), @@ -1228,6 +1230,7 @@ function extractFunctionInScope( checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), scope, NodeBuilderFlags.NoTruncation, + InternalNodeBuilderFlags.AllowUnresolvedNames, ); typeElements.push(factory.createPropertySignature( @@ -1378,7 +1381,7 @@ function extractConstantInScope( let variableType = isJS || !checker.isContextSensitive(node) ? undefined - : checker.typeToTypeNode(checker.getContextualType(node)!, scope, NodeBuilderFlags.NoTruncation); // TODO: GH#18217 + : checker.typeToTypeNode(checker.getContextualType(node)!, scope, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames); // TODO: GH#18217 let initializer = transformConstantInitializer(skipParentheses(node), substitutions); @@ -1512,7 +1515,7 @@ function extractConstantInScope( const paramType = checker.getTypeAtLocation(p); if (paramType === checker.getAnyType()) hasAny = true; - parameters.push(factory.updateParameterDeclaration(p, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || checker.typeToTypeNode(paramType, scope, NodeBuilderFlags.NoTruncation), p.initializer)); + parameters.push(factory.updateParameterDeclaration(p, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || checker.typeToTypeNode(paramType, scope, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames), p.initializer)); } } // If a parameter was inferred as any we skip adding function parameters at all. @@ -1521,7 +1524,7 @@ function extractConstantInScope( if (hasAny) return { variableType, initializer }; variableType = undefined; if (isArrowFunction(initializer)) { - initializer = factory.updateArrowFunction(initializer, canHaveModifiers(node) ? getModifiers(node) : undefined, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, NodeBuilderFlags.NoTruncation), initializer.equalsGreaterThanToken, initializer.body); + initializer = factory.updateArrowFunction(initializer, canHaveModifiers(node) ? getModifiers(node) : undefined, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames), initializer.equalsGreaterThanToken, initializer.body); } else { if (functionSignature && !!functionSignature.thisParameter) { @@ -1538,7 +1541,7 @@ function extractConstantInScope( /*dotDotDotToken*/ undefined, "this", /*questionToken*/ undefined, - checker.typeToTypeNode(thisType, scope, NodeBuilderFlags.NoTruncation), + checker.typeToTypeNode(thisType, scope, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames), ), ); } diff --git a/src/services/refactors/inferFunctionReturnType.ts b/src/services/refactors/inferFunctionReturnType.ts index 42607e3888bda..d147fbbed19b9 100644 --- a/src/services/refactors/inferFunctionReturnType.ts +++ b/src/services/refactors/inferFunctionReturnType.ts @@ -11,6 +11,7 @@ import { FunctionExpression, getLocaleSpecificMessage, getTouchingPropertyName, + InternalNodeBuilderFlags, isArrowFunction, isBlock, isInJSFile, @@ -126,7 +127,7 @@ function getInfo(context: RefactorContext): FunctionInfo | RefactorErrorInfo | u if (signature) { const typePredicate = typeChecker.getTypePredicateOfSignature(signature); if (typePredicate && typePredicate.type) { - const typePredicateTypeNode = typeChecker.typePredicateToTypePredicateNode(typePredicate, declaration, NodeBuilderFlags.NoTruncation); + const typePredicateTypeNode = typeChecker.typePredicateToTypePredicateNode(typePredicate, declaration, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames); if (typePredicateTypeNode) { return { declaration, returnTypeNode: typePredicateTypeNode }; } @@ -141,7 +142,7 @@ function getInfo(context: RefactorContext): FunctionInfo | RefactorErrorInfo | u return { error: getLocaleSpecificMessage(Diagnostics.Could_not_determine_function_return_type) }; } - const returnTypeNode = typeChecker.typeToTypeNode(returnType, declaration, NodeBuilderFlags.NoTruncation); + const returnTypeNode = typeChecker.typeToTypeNode(returnType, declaration, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames); if (returnTypeNode) { return { declaration, returnTypeNode }; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 55ab684196e3c..c3908e208b74f 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -132,6 +132,7 @@ import { ImportTypeNode, indexOfNode, IndexSignatureDeclaration, + InternalNodeBuilderFlags, InternalSymbolName, isAmbientModule, isAnyImportSyntax, @@ -3440,7 +3441,7 @@ export function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, progra const checker = program.getTypeChecker(); let typeIsAccessible = true; const notAccessible = () => typeIsAccessible = false; - const res = checker.typeToTypeNode(type, enclosingScope, NodeBuilderFlags.NoTruncation, { + const res = checker.typeToTypeNode(type, enclosingScope, NodeBuilderFlags.NoTruncation, InternalNodeBuilderFlags.AllowUnresolvedNames, { trackSymbol: (symbol, declaration, meaning) => { typeIsAccessible = typeIsAccessible && checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility === SymbolAccessibility.Accessible; return !typeIsAccessible;