From 1ea970e4116a52b45b3291d8d319ea03a33a1153 Mon Sep 17 00:00:00 2001 From: Titian Cernicova-Dragomir Date: Wed, 29 Nov 2023 07:25:55 -0500 Subject: [PATCH] Improve declaration emit type safety. Signed-off-by: Titian Cernicova-Dragomir --- src/compiler/transformers/declarations.ts | 110 +++++++----------- .../transformers/declarations/emitResolver.ts | 6 +- .../declarations/localInferenceResolver.ts | 50 ++++---- .../declarations/transpileDeclaration.ts | 55 ++------- .../transformers/declarations/types.ts | 58 +++------ src/compiler/types.ts | 37 +++--- src/compiler/visitorPublic.ts | 50 ++++---- tests/baselines/reference/api/typescript.d.ts | 18 +-- 8 files changed, 148 insertions(+), 236 deletions(-) diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 24383a4a9cd98..8efbf541d2b5d 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -23,6 +23,7 @@ import { ConstructorTypeNode, ConstructSignatureDeclaration, contains, + CoreEmitResolver, createDiagnosticForNode, createDiagnosticForRange, createEmptyExports, @@ -46,7 +47,6 @@ import { EnumDeclaration, ExportAssignment, ExportDeclaration, - Expression, ExpressionWithTypeArguments, factory, FileReference, @@ -139,7 +139,7 @@ import { isMethodSignature, isModifier, isModuleDeclaration, - IsolatedEmitResolver, + IsolatedTransformationContext, isOmittedExpression, isPrivateIdentifier, isPropertySignature, @@ -167,7 +167,6 @@ import { LateBoundDeclaration, LateVisibilityPaintedStatement, length, - LocalInferenceResolver, map, mapDefined, MethodDeclaration, @@ -293,7 +292,7 @@ const declarationEmitNodeBuilderFlags = NodeBuilderFlags.MultilineObjectLiterals * * @internal */ -export function transformDeclarations(context: TransformationContext, _useTscEmit = true) { +export function transformDeclarations(context: (TransformationContext & { useTscEmit?: true; }) | IsolatedTransformationContext) { const throwDiagnostic = () => Debug.fail("Diagnostic emitted without context"); let getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic = throwDiagnostic; let needsDeclare = true; @@ -323,48 +322,25 @@ export function transformDeclarations(context: TransformationContext, _useTscEmi const { noResolve, stripInternal } = options; return transformRoot; - function createTransformerServices(): { - isolatedDeclarations: true; - useTscEmit: false; - resolver: IsolatedEmitResolver; - localInferenceResolver: LocalInferenceResolver; - host: undefined; - symbolTracker: undefined; - ensureNoInitializer: (node: CanHaveLiteralInitializer) => Expression | undefined; - } | { - isolatedDeclarations: true; - useTscEmit: true; - resolver: EmitResolver; - localInferenceResolver: LocalInferenceResolver; - host: EmitHost; - symbolTracker: SymbolTracker; - ensureNoInitializer: (node: CanHaveLiteralInitializer) => Expression | undefined; - } | { - isolatedDeclarations: false; - useTscEmit: false; - resolver: EmitResolver; - localInferenceResolver: undefined; - host: EmitHost; - symbolTracker: SymbolTracker; - ensureNoInitializer: (node: CanHaveLiteralInitializer) => Expression | undefined; - } { - const { isolatedDeclarations, resolver: localInferenceResolver } = createLocalInferenceResolver({ - ensureParameter, - context, - visitDeclarationSubtree, - setEnclosingDeclarations(node) { - const oldNode = enclosingDeclaration; - enclosingDeclaration = node; - return oldNode; - }, - checkEntityNameVisibility(name, container) { - return checkEntityNameVisibility(name, container ?? enclosingDeclaration); - }, - }); + function createTransformerServices() { + const isolatedDeclarations = context.getCompilerOptions().isolatedDeclarations; if (isolatedDeclarations) { - if (!_useTscEmit) { - const resolver: IsolatedEmitResolver = context.getEmitResolver(); + const localInferenceResolver = createLocalInferenceResolver({ + ensureParameter, + context, + visitDeclarationSubtree, + setEnclosingDeclarations(node) { + const oldNode = enclosingDeclaration; + enclosingDeclaration = node; + return oldNode; + }, + checkEntityNameVisibility(name, container) { + return checkEntityNameVisibility(name, container ?? enclosingDeclaration); + }, + }); + if (!context.useTscEmit) { + const resolver: CoreEmitResolver = context.getEmitResolver(); // Ideally nothing should require the symbol tracker in isolated declarations mode. // createLiteralConstValue is the one exception const emptySymbolTracker = {}; @@ -375,13 +351,8 @@ export function transformDeclarations(context: TransformationContext, _useTscEmi localInferenceResolver, symbolTracker: undefined, host: undefined, - ensureNoInitializer: (node: CanHaveLiteralInitializer) => { - if (shouldPrintWithInitializer(node)) { - return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, emptySymbolTracker); // TODO: Make safe - } - return undefined; - }, - }; + ensureNoInitializer: createEnsureNoInitializer(emptySymbolTracker), + } as const; } else { const host = context.getEmitHost(); @@ -394,33 +365,33 @@ export function transformDeclarations(context: TransformationContext, _useTscEmi localInferenceResolver, symbolTracker, host, - ensureNoInitializer: (node: CanHaveLiteralInitializer) => { - if (shouldPrintWithInitializer(node)) { - return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe - } - return undefined; - }, - }; + ensureNoInitializer: createEnsureNoInitializer(symbolTracker), + } as const; } } else { + Debug.assert(context.useTscEmit === true || context.useTscEmit === undefined); const host = context.getEmitHost(); const resolver = context.getEmitResolver(); const symbolTracker: SymbolTracker = createSymbolTracker(resolver, host); return { - isolatedDeclarations, + isolatedDeclarations: false, useTscEmit: false, - localInferenceResolver, + localInferenceResolver: undefined, resolver, symbolTracker, host, - ensureNoInitializer: (node: CanHaveLiteralInitializer) => { - if (shouldPrintWithInitializer(node)) { - return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe - } - return undefined; - }, - }; + ensureNoInitializer: createEnsureNoInitializer(symbolTracker), + } as const; + } + + function createEnsureNoInitializer(symbolTracker: SymbolTracker) { + return function ensureNoInitializer(node: CanHaveLiteralInitializer) { + if (shouldPrintWithInitializer(node)) { + return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe + } + return undefined; + } } } function reportIsolatedDeclarationError(node: Node) { @@ -659,6 +630,7 @@ export function transformDeclarations(context: TransformationContext, _useTscEmi libs = new Map(); existingTypeReferencesSources = node.sourceFiles; let hasNoDefaultLib = false; + Debug.assert(!isolatedDeclarations, "Bundles are not supported in isolated declarations"); const bundle = factory.createBundle( map(node.sourceFiles, sourceFile => { if (sourceFile.isDeclarationFile) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217 @@ -681,7 +653,7 @@ export function transformDeclarations(context: TransformationContext, _useTscEmi sourceFile, [factory.createModuleDeclaration( [factory.createModifier(SyntaxKind.DeclareKeyword)], - factory.createStringLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), + factory.createStringLiteral(getResolvedExternalModuleName(host, sourceFile)), factory.createModuleBlock(setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)), )], /*isDeclarationFile*/ true, @@ -1121,7 +1093,7 @@ export function transformDeclarations(context: TransformationContext, _useTscEmi if (isBundledEmit) { // Bundle emit not supported for isolatedDeclarations if (!isolatedDeclarations) { - const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent); + const newName = getExternalModuleNameFromDeclaration(host, resolver, parent); if (newName) { return factory.createStringLiteral(newName); } diff --git a/src/compiler/transformers/declarations/emitResolver.ts b/src/compiler/transformers/declarations/emitResolver.ts index 9309b193717be..1c9f21f9bb8a6 100644 --- a/src/compiler/transformers/declarations/emitResolver.ts +++ b/src/compiler/transformers/declarations/emitResolver.ts @@ -1,6 +1,7 @@ import { bindSourceFileForDeclarationEmit, ComputedPropertyName, + CoreEmitResolver, createEntityVisibilityChecker, createEvaluator, Debug, @@ -39,7 +40,6 @@ import { isIdentifier, isInfinityOrNaNString, isNumericLiteral, - IsolatedEmitResolver, isPrefixUnaryExpression, isPrimitiveLiteralValue, isPropertyAccessExpression, @@ -70,7 +70,7 @@ import { } from "../../_namespaces/ts"; /** @internal */ -export function createEmitDeclarationResolver(file: SourceFile): IsolatedEmitResolver { +export function createEmitDeclarationResolver(file: SourceFile): CoreEmitResolver { const { getNodeLinks, resolveMemberKey, resolveName, resolveEntityName } = bindSourceFileForDeclarationEmit(file); const { isEntityNameVisible } = createEntityVisibilityChecker({ @@ -394,4 +394,4 @@ export function createEmitDeclarationResolver(file: SourceFile): IsolatedEmitRes return false; } -} + } diff --git a/src/compiler/transformers/declarations/localInferenceResolver.ts b/src/compiler/transformers/declarations/localInferenceResolver.ts index a675271b2122b..64fb78caf2acd 100644 --- a/src/compiler/transformers/declarations/localInferenceResolver.ts +++ b/src/compiler/transformers/declarations/localInferenceResolver.ts @@ -31,6 +31,7 @@ import { isMethodOrAccessor, isNoSubstitutionTemplateLiteral, isNumericLiteral, + IsolatedTransformationContext, isOmittedExpression, isOptionalDeclaration, isParameter, @@ -120,44 +121,39 @@ export function createLocalInferenceResolver({ visitDeclarationSubtree(input: Node): VisitResult; checkEntityNameVisibility(name: EntityNameOrEntityNameExpression, container?: Node): void; ensureParameter(p: ParameterDeclaration): ParameterDeclaration; - context: TransformationContext; -}): { resolver: LocalInferenceResolver; isolatedDeclarations: true; } | { resolver: undefined; isolatedDeclarations: false; } { + context: IsolatedTransformationContext | TransformationContext; +}): LocalInferenceResolver { let currentSourceFile: SourceFile; const options = context.getCompilerOptions(); const resolver = context.getEmitResolver(); - if (!options.isolatedDeclarations) { - return { resolver: undefined, isolatedDeclarations: false }; - } + Debug.assert(options.isolatedDeclarations, "createLocalInferenceResolver can only be called when isolatedDeclarations is true"); const { factory } = context; let inferenceContext: { isInvalid: boolean; disableErrors: boolean; } = undefined!; const strictNullChecks = !!options.strict || !!options.strictNullChecks; return { - resolver: { - fromInitializer(node: HasInferredType | ExportAssignment, type: TypeNode | undefined, sourceFile: SourceFile) { - const oldSourceFile = currentSourceFile; - const hasExistingContext = inferenceContext !== undefined; - if (!hasExistingContext) { - inferenceContext = { isInvalid: false, disableErrors: false }; - } - currentSourceFile = sourceFile; - try { - const typeNode = localInferenceFromInitializer(node, type); - if (typeNode !== undefined) { - return { isInvalid: inferenceContext.isInvalid, typeNode }; - } - return { isInvalid: true, typeNode: invalid(node) }; + fromInitializer(node: HasInferredType | ExportAssignment, type: TypeNode | undefined, sourceFile: SourceFile) { + const oldSourceFile = currentSourceFile; + const hasExistingContext = inferenceContext !== undefined; + if (!hasExistingContext) { + inferenceContext = { isInvalid: false, disableErrors: false }; + } + currentSourceFile = sourceFile; + try { + const typeNode = localInferenceFromInitializer(node, type); + if (typeNode !== undefined) { + return { isInvalid: inferenceContext.isInvalid, typeNode }; } - finally { - currentSourceFile = oldSourceFile; - if (!hasExistingContext) { - inferenceContext = undefined!; - } + return { isInvalid: true, typeNode: invalid(node) }; + } + finally { + currentSourceFile = oldSourceFile; + if (!hasExistingContext) { + inferenceContext = undefined!; } - }, - makeInvalidType, + } }, - isolatedDeclarations: options.isolatedDeclarations, + makeInvalidType, }; function hasParseError(node: Node) { return !!(node.flags & NodeFlags.ThisNodeHasError); diff --git a/src/compiler/transformers/declarations/transpileDeclaration.ts b/src/compiler/transformers/declarations/transpileDeclaration.ts index bddb4afb78989..4cf777c6a287b 100644 --- a/src/compiler/transformers/declarations/transpileDeclaration.ts +++ b/src/compiler/transformers/declarations/transpileDeclaration.ts @@ -11,7 +11,6 @@ import { Diagnostic, EmitHost, ensureTrailingDirectorySeparator, - factory, getAreDeclarationMapsEnabled, getBaseFileName, getDeclarationEmitOutputFilePathWorker, @@ -22,74 +21,44 @@ import { getSourceFilePathInNewDir, normalizePath, normalizeSlashes, + nullTransformationContext, PrinterOptions, SourceFile, SourceMapGenerator, sys, - TransformationContext, transformDeclarations, TranspileDeclarationsOptions, TranspileDeclarationsOutput, } from "../../_namespaces/ts"; -function createEmitDeclarationHost(options: TranspileDeclarationsOptions): EmitHost { - const throws = () => Debug.fail("Function should not be called in isolated declarations emit"); - return { - getCurrentDirectory: () => options.currentDirectory ?? ".", - getCanonicalFileName: createGetCanonicalFileName(sys.useCaseSensitiveFileNames), - useCaseSensitiveFileNames: () => !!options.useCaseSensitiveFileNames, - getCompilerOptions: () => options.compilerOptions, - getCommonSourceDirectory: () => ensureTrailingDirectorySeparator(options.commonSourceDirectory ?? "."), - get redirectTargetsMap(): never { - Debug.fail("redirectTargetsMap should not be used in isolated declarations"); - return undefined!; // Need return despite fail call GH#52214 - }, - directoryExists: throws, - fileExists: throws, - readFile: throws, - realpath: throws, - getLibFileFromReference: throws, - getSourceFileFromReference: throws, - isSourceOfProjectReferenceRedirect: throws, - - getSourceFiles: throws, - isEmitBlocked: throws, - getPrependNodes: throws, - writeFile: throws, - getBuildInfo: throws, - getSourceFile: throws, - getSourceFileByPath: throws, - getProjectReferenceRedirect: throws, - getFileIncludeReasons: throws, - isSourceFileFromExternalLibrary: throws, - getResolvedProjectReferenceToRedirect: throws, - }; -} - export function transpileDeclaration(sourceFile: SourceFile, transpileOptions: TranspileDeclarationsOptions): TranspileDeclarationsOutput { const compilerOptions: CompilerOptions = { ...transpileOptions.compilerOptions, isolatedDeclarations: true, traceResolution: false, }; - const emitHost = createEmitDeclarationHost(transpileOptions); + const emitHost = { + getCurrentDirectory: () => transpileOptions.currentDirectory ?? ".", + getCanonicalFileName: createGetCanonicalFileName(!!compilerOptions.useCaseSensitiveFileNames), + useCaseSensitiveFileNames: () => !!compilerOptions.useCaseSensitiveFileNames, + getCompilerOptions: () => compilerOptions.compilerOptions, + getCommonSourceDirectory: () => ensureTrailingDirectorySeparator(transpileOptions.commonSourceDirectory ?? "."), + }; const emitResolver = createEmitDeclarationResolver(sourceFile); const diagnostics: Diagnostic[] = []; const transformer = transformDeclarations({ - getEmitHost() { - return emitHost; - }, + useTscEmit: false, + ...nullTransformationContext, getEmitResolver() { return emitResolver; }, getCompilerOptions() { - return emitHost.getCompilerOptions(); + return compilerOptions; }, - factory, addDiagnostic(diag: any) { diagnostics.push(diag); }, - } as TransformationContext, /*useTscEmit*/ false); + }); const result = transformer(sourceFile); const printer = createPrinter({ diff --git a/src/compiler/transformers/declarations/types.ts b/src/compiler/transformers/declarations/types.ts index 8401469892efa..a6569ae1135b6 100644 --- a/src/compiler/transformers/declarations/types.ts +++ b/src/compiler/transformers/declarations/types.ts @@ -1,51 +1,21 @@ import { - AccessorDeclaration, - AllAccessorDeclarations, - AnyImportSyntax, - ComputedPropertyName, - Declaration, - ElementAccessExpression, - EntityNameOrEntityNameExpression, - EnumMember, - Expression, - FunctionDeclaration, - ImportDeclaration, - LateBoundDeclaration, - Node, - ParameterDeclaration, - PropertyAccessExpression, - PropertyDeclaration, - PropertySignature, - ResolutionMode, - SignatureDeclaration, - StringLiteralLike, - Symbol, - SymbolTracker, - SymbolVisibilityResult, - VariableDeclaration, + CompilerOptions, + CoreEmitResolver, + CoreTransformationContext, + Diagnostic, + NodeFactory, } from "../../_namespaces/ts"; +/** @internal */ +export interface IsolatedTransformationContext extends CoreTransformationContext { + useTscEmit: false; + getEmitResolver(): CoreEmitResolver; + getCompilerOptions(): CompilerOptions; + factory: NodeFactory; + addDiagnostic(diag: Diagnostic): void; +} + /** @internal */ export type MemberKey = string & { __memberKey: void; }; - -/** @internal */ -export interface IsolatedEmitResolver { - isLiteralComputedName(node: ComputedPropertyName): boolean; - isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; - isLateBound(node: Declaration): node is LateBoundDeclaration; - isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined; - isExpandoFunction(node: VariableDeclaration | FunctionDeclaration): boolean; - createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker): Expression; - isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; - isOptionalParameter(node: ParameterDeclaration): boolean; - getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): [specifier: string, mode: ResolutionMode | undefined][] | undefined; - isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean; - getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined; - isImportRequiredByAugmentation(decl: ImportDeclaration): boolean; - getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined; - getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations; - tryFindAmbientModule(moduleReferenceExpression: Expression): Symbol | undefined; - getPropertiesOfContainerFunction(node: FunctionDeclaration | VariableDeclaration): Symbol[] -} diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 05dc55050808d..df515488492e8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5665,8 +5665,28 @@ export enum TypeReferenceSerializationKind { ObjectType, } + +/** @internal */ +export interface CoreEmitResolver { + isLiteralComputedName(node: ComputedPropertyName): boolean; + isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; + isLateBound(node: Declaration): node is LateBoundDeclaration; + isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined; + isExpandoFunction(node: VariableDeclaration | FunctionDeclaration): boolean; + createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker): Expression; + isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; + isOptionalParameter(node: ParameterDeclaration): boolean; + getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): [specifier: string, mode: ResolutionMode | undefined][] | undefined; + isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean; + getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined; + isImportRequiredByAugmentation(decl: ImportDeclaration): boolean; + getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined; + getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations; + tryFindAmbientModule(moduleReferenceExpression: Expression): Symbol | undefined; + getPropertiesOfContainerFunction(node: FunctionDeclaration | VariableDeclaration): Symbol[] +} /** @internal */ -export interface EmitResolver { +export interface EmitResolver extends CoreEmitResolver { hasGlobalName(name: string): boolean; getReferencedExportContainer(node: Identifier, prefixLocals?: boolean): SourceFile | ModuleDeclaration | EnumDeclaration | undefined; getReferencedImportDeclaration(node: Identifier): Declaration | undefined; @@ -5676,41 +5696,26 @@ export interface EmitResolver { isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean; isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean; getNodeCheckFlags(node: Node): NodeCheckFlags; - isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; - isLateBound(node: Declaration): node is LateBoundDeclaration; collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined; - isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; - isExpandoFunction(node: FunctionDeclaration | VariableDeclaration): boolean; - getPropertiesOfContainerFunction(node: Declaration): Symbol[]; createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression | ElementAccessExpression | BinaryExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined; createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, 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; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant - getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined; getReferencedValueDeclaration(reference: Identifier): Declaration | undefined; getReferencedValueDeclarations(reference: Identifier): Declaration[] | undefined; getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind; - isOptionalParameter(node: ParameterDeclaration): boolean; moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean; isArgumentsLocalBinding(node: Identifier): boolean; getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode | ImportCall): SourceFile | undefined; - getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): [specifier: string, mode: ResolutionMode][] | undefined; getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): [specifier: string, mode: ResolutionMode][] | undefined; - isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration | EnumMember): boolean; - isLiteralComputedName(name: ComputedPropertyName): boolean; getJsxFactoryEntity(location?: Node): EntityName | undefined; getJsxFragmentFactoryEntity(location?: Node): EntityName | undefined; - getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations; - getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined; isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean; getDeclarationStatementsForSourceFile(node: SourceFile, flags: NodeBuilderFlags, tracker: SymbolTracker, bundled?: boolean): Statement[] | undefined; isImportRequiredByAugmentation(decl: ImportDeclaration): boolean; - tryFindAmbientModule(moduleReferenceExpression: Expression): Symbol | undefined; } // dprint-ignore diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index c5e99d170911c..2b2f8b31430ac 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1,5 +1,6 @@ import { ConciseBody, + CoreTransformationContext, Debug, EmitFlags, Expression, @@ -99,7 +100,6 @@ import { some, Statement, SyntaxKind, - TransformationContext, Visitor, } from "./_namespaces/ts"; @@ -377,7 +377,7 @@ function visitArrayWorker( * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ -export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { +export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: CoreTransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { context.startLexicalEnvironment(); statements = nodesVisitor(statements, visitor, isStatement, start); if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements); @@ -388,9 +388,9 @@ export function visitLexicalEnvironment(statements: NodeArray, visito * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ -export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; -export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; -export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { +export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: NodesVisitor): NodeArray; +export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; +export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: CoreTransformationContext, nodesVisitor = visitNodes) { let updated: NodeArray | undefined; context.startLexicalEnvironment(); if (nodes) { @@ -415,7 +415,7 @@ export function visitParameterList(nodes: NodeArray | unde return updated; } -function addDefaultValueAssignmentsIfNeeded(parameters: NodeArray, context: TransformationContext) { +function addDefaultValueAssignmentsIfNeeded(parameters: NodeArray, context: CoreTransformationContext) { let result: ParameterDeclaration[] | undefined; for (let i = 0; i < parameters.length; i++) { const parameter = parameters[i]; @@ -431,7 +431,7 @@ function addDefaultValueAssignmentsIfNeeded(parameters: NodeArray, visitor: * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ -export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; +export function visitEachChild(node: T, visitor: Visitor, context: CoreTransformationContext): T; /** @internal */ -export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures +export function visitEachChild(node: T, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -590,10 +590,10 @@ export function visitEachChild(node: T, visitor: Visitor, contex * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ -export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; +export function visitEachChild(node: T | undefined, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; /** @internal */ -export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; -export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { +export function visitEachChild(node: T | undefined, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; +export function visitEachChild(node: T | undefined, visitor: Visitor, context: CoreTransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { if (node === undefined) { return undefined; } @@ -602,7 +602,7 @@ export function visitEachChild(node: T | undefined, visitor: Vis return fn === undefined ? node : fn(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor); } -type VisitEachChildFunction = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; +type VisitEachChildFunction = (node: T, visitor: Visitor, context: CoreTransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; // A type that correlates a `SyntaxKind` to a `VisitEachChildFunction`, for nodes in the `HasChildren` union. // This looks something like: diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 176326ba46b78..6bb15bac55050 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -9812,32 +9812,32 @@ declare namespace ts { * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; + function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: CoreTransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: CoreTransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: CoreTransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: CoreTransformationContext): ConciseBody; /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + function visitIterationBody(body: Statement, visitor: Visitor, context: CoreTransformationContext): Statement; /** * Visits the elements of a {@link CommaListExpression}. * @param visitor The visitor to use when visiting expressions whose result will not be discarded at runtime. @@ -9851,7 +9851,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + function visitEachChild(node: T, visitor: Visitor, context: CoreTransformationContext): T; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -9859,7 +9859,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; + function visitEachChild(node: T | undefined, visitor: Visitor, context: CoreTransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; function transpileDeclaration(sourceFile: SourceFile, transpileOptions: TranspileDeclarationsOptions): TranspileDeclarationsOutput; function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[];