• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import {
2    AccessorDeclaration, addRelatedInfo, AllAccessorDeclarations, AnnotationPropertyDeclaration, AnyImportSyntax, append, ArrayBindingElement,
3    arrayFrom, AssertClause, BindingElement, BindingName, BindingPattern, Bundle, CallSignatureDeclaration,
4    canHaveModifiers, canProduceDiagnostics, ClassDeclaration, CommentRange, compact, concatenate,
5    concatenateDecoratorsAndModifiers, ConditionalTypeNode, ConstructorDeclaration, ConstructorTypeNode,
6    ConstructSignatureDeclaration, contains, createDiagnosticForNode, createEmptyExports,
7    createGetSymbolAccessibilityDiagnosticForNode, createGetSymbolAccessibilityDiagnosticForNodeName, createSymbolTable,
8    createUnparsedSourceFile, Debug, Declaration, DeclarationDiagnosticProducing, DeclarationName,
9    declarationNameToString, Decorator, Diagnostics, DiagnosticWithLocation, EmitFlags, EmitHost, EmitResolver, emptyArray,
10    ensureEtsDecorators, EntityNameOrEntityNameExpression, EnumDeclaration, ESMap, ExportAssignment, ExportDeclaration,
11    ExpressionWithTypeArguments, factory, FileReference, filter, flatMap, flatten, forEach, FunctionDeclaration,
12    FunctionTypeNode, GeneratedIdentifierFlags, GetAccessorDeclaration, getAnnotations, getCommentRange, getDirectoryPath,
13    getEffectiveBaseTypeNode, getEffectiveDecorators, getEffectiveModifierFlags,
14    getExternalModuleImportEqualsDeclarationExpression, getExternalModuleNameFromDeclaration,
15    getFirstConstructorWithBody, getLeadingCommentRanges, getLeadingCommentRangesOfNode, getLineAndCharacterOfPosition,
16    getNameOfDeclaration, getOriginalNodeId, getOutputPathsFor, getParseTreeNode, getRelativePathToDirectoryOrUrl,
17    getReservedDecoratorsOfEtsFile, getReservedDecoratorsOfStructDeclaration, getResolutionModeOverrideForClause,
18    getResolvedExternalModuleName, getSetAccessorValueParameter, getSourceFileOfNode, GetSymbolAccessibilityDiagnostic,
19    getTextOfNode, getThisParameter, getTrailingCommentRanges, hasDynamicName, hasEffectiveModifier, hasExtension,
20    hasJSDocNodes, HasModifiers, hasSyntacticModifier, HeritageClause, Identifier, ImportDeclaration,
21    ImportEqualsDeclaration, ImportTypeNode, IndexSignatureDeclaration, inEtsStylesContext, InterfaceDeclaration, isAnnotation, isAnnotationDeclaration,
22    isAnyImportSyntax, isArray, isBindingPattern, isCallExpression, isClassDeclaration, isDeclaration, isEntityName,
23    isEntityNameExpression, isExportAssignment, isExportDeclaration, isExternalModule, isExternalModuleAugmentation,
24    isExternalModuleIndicator, isExternalModuleReference, isExternalOrCommonJsModule, isFunctionDeclaration,
25    isFunctionLike, isGlobalScopeAugmentation, isIdentifier, isImportDeclaration, isImportEqualsDeclaration,
26    isIndexSignatureDeclaration, isInEtsFile, isInterfaceDeclaration, isJsonSourceFile,
27    isLateVisibilityPaintedStatement, isLiteralImportTypeNode, isMappedTypeNode, isMethodDeclaration, isMethodSignature,
28    isModifier, isModuleDeclaration, isNightly, isOHModulesReference, isOhpm, isOmittedExpression, isPrivateIdentifier,
29    isPropertyAccessExpression, isPropertySignature, isSemicolonClassElement, isSendableFunctionOrType,
30    isSetAccessorDeclaration, isSourceFile, isSourceFileJS, isSourceFileNotJson, isStringANonContextualKeyword,
31    isStringLiteral, isStringLiteralLike, isStructDeclaration, isTupleTypeNode, isTypeAliasDeclaration, isTypeNode,
32    isTypeParameterDeclaration, isTypeQueryNode, isTypeReferenceNode, isUnparsedSource, last, LateBoundDeclaration,
33    LateVisibilityPaintedStatement, length, map, Map, mapDefined, MethodDeclaration, MethodSignature, Modifier,
34    ModifierFlags, ModuleBody, ModuleDeclaration, Mutable, NamedDeclaration, NamespaceDeclaration,
35    needsScopeMarker, Node, NodeArray, NodeBuilderFlags, NodeFlags, NodeId, normalizeSlashes, OmittedExpression,
36    orderedRemoveItem, ParameterDeclaration, parseNodeFactory, pathContainsNodeModules, pathIsRelative,
37    PropertyDeclaration, PropertySignature, pushIfUnique, removeAllComments, Set, SetAccessorDeclaration,
38    setCommentRange, setEmitFlags, setOriginalNode, setParent, setTextRange, SignatureDeclaration, skipTrivia, some,
39    SourceFile, startsWith, Statement, stringContains, StringLiteral, Symbol, SymbolAccessibility,
40    SymbolAccessibilityResult, SymbolFlags, SymbolTracker, SyntaxKind, toFileNameLowerCase, toPath,
41    TransformationContext, transformNodes, tryCast, TypeAliasDeclaration, TypeNode, TypeParameterDeclaration,
42    TypeReferenceNode, unescapeLeadingUnderscores, UnparsedSource, VariableDeclaration, VariableStatement, visitArray,
43    visitEachChild, visitNode, visitNodes, VisitResult,
44} from "../_namespaces/ts";
45import * as moduleSpecifiers from "../_namespaces/ts.moduleSpecifiers";
46
47/** @internal */
48export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined {
49    const compilerOptions = host.getCompilerOptions();
50    const result = transformNodes(resolver, host, factory, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false);
51    return result.diagnostics;
52}
53
54function hasInternalAnnotation(range: CommentRange, currentSourceFile: SourceFile) {
55    const comment = currentSourceFile.text.substring(range.pos, range.end);
56    return stringContains(comment, "@internal");
57}
58
59export function isInternalDeclaration(node: Node, currentSourceFile: SourceFile) {
60    const parseTreeNode = getParseTreeNode(node);
61    if (parseTreeNode && parseTreeNode.kind === SyntaxKind.Parameter) {
62        const paramIdx = (parseTreeNode.parent as SignatureDeclaration).parameters.indexOf(parseTreeNode as ParameterDeclaration);
63        const previousSibling = paramIdx > 0 ? (parseTreeNode.parent as SignatureDeclaration).parameters[paramIdx - 1] : undefined;
64        const text = currentSourceFile.text;
65        const commentRanges = previousSibling
66            ? concatenate(
67                // to handle
68                // ... parameters, /** @internal */
69                // public param: string
70                getTrailingCommentRanges(text, skipTrivia(text, previousSibling.end + 1, /* stopAfterLineBreak */ false, /* stopAtComments */ true)),
71                getLeadingCommentRanges(text, node.pos)
72            )
73            : getTrailingCommentRanges(text, skipTrivia(text, node.pos, /* stopAfterLineBreak */ false, /* stopAtComments */ true));
74        return commentRanges && commentRanges.length && hasInternalAnnotation(last(commentRanges), currentSourceFile);
75    }
76    const leadingCommentRanges = parseTreeNode && getLeadingCommentRangesOfNode(parseTreeNode, currentSourceFile);
77    return !!forEach(leadingCommentRanges, range => {
78        return hasInternalAnnotation(range, currentSourceFile);
79    });
80}
81
82const declarationEmitNodeBuilderFlags =
83    NodeBuilderFlags.MultilineObjectLiterals |
84    NodeBuilderFlags.WriteClassExpressionAsTypeLiteral |
85    NodeBuilderFlags.UseTypeOfFunction |
86    NodeBuilderFlags.UseStructuralFallback |
87    NodeBuilderFlags.AllowEmptyTuple |
88    NodeBuilderFlags.GenerateNamesForShadowedTypeParams |
89    NodeBuilderFlags.NoTruncation;
90
91/**
92 * Transforms a ts file into a .d.ts or .d.ets file
93 * This process requires type information, which is retrieved through the emit resolver. Because of this,
94 * in many places this transformer assumes it will be operating on parse tree nodes directly.
95 * This means that _no transforms should be allowed to occur before this one_.
96 *
97 * @internal
98 */
99
100export function transformDeclarations(context: TransformationContext) {
101    const throwDiagnostic = () => Debug.fail("Diagnostic emitted without context");
102    let getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic = throwDiagnostic;
103    let needsDeclare = true;
104    let isBundledEmit = false;
105    let resultHasExternalModuleIndicator = false;
106    let needsScopeFixMarker = false;
107    let resultHasScopeMarker = false;
108    let enclosingDeclaration: Node;
109    let necessaryTypeReferences: Set<[specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined]> | undefined;
110    let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined;
111    let lateStatementReplacementMap: ESMap<NodeId, VisitResult<LateVisibilityPaintedStatement | ExportAssignment>>;
112    let suppressNewDiagnosticContexts: boolean;
113    let exportedModulesFromDeclarationEmit: Symbol[] | undefined;
114
115    const { factory } = context;
116    const host = context.getEmitHost();
117    const symbolTracker: SymbolTracker = {
118        trackSymbol,
119        reportInaccessibleThisError,
120        reportInaccessibleUniqueSymbolError,
121        reportCyclicStructureError,
122        reportPrivateInBaseOfClassExpression,
123        reportLikelyUnsafeImportRequiredError,
124        reportTruncationError,
125        moduleResolverHost: host,
126        trackReferencedAmbientModule,
127        trackExternalModuleSymbolOfImportTypeNode,
128        reportNonlocalAugmentation,
129        reportNonSerializableProperty,
130        reportImportTypeNodeResolutionModeOverride,
131    };
132    let errorNameNode: DeclarationName | undefined;
133    let errorFallbackNode: Declaration | undefined;
134
135    let currentSourceFile: SourceFile;
136    let refs: ESMap<NodeId, SourceFile>;
137    let libs: ESMap<string, boolean>;
138    let emittedImports: readonly AnyImportSyntax[] | undefined; // must be declared in container so it can be `undefined` while transformer's first pass
139    const resolver = context.getEmitResolver();
140    const options = context.getCompilerOptions();
141    const { noResolve, stripInternal, isolatedDeclarations } = options;
142    return transformRoot;
143
144    function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives: readonly [specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined][] | undefined): void {
145        if (!typeReferenceDirectives) {
146            return;
147        }
148        necessaryTypeReferences = necessaryTypeReferences || new Set();
149        for (const ref of typeReferenceDirectives) {
150            necessaryTypeReferences.add(ref);
151        }
152    }
153
154    function trackReferencedAmbientModule(node: ModuleDeclaration, symbol: Symbol) {
155        // If it is visible via `// <reference types="..."/>`, then we should just use that
156        const directives = resolver.getTypeReferenceDirectivesForSymbol(symbol, SymbolFlags.All);
157        if (length(directives)) {
158            return recordTypeReferenceDirectivesIfNecessary(directives);
159        }
160        // Otherwise we should emit a path-based reference
161        const container = getSourceFileOfNode(node);
162        refs.set(getOriginalNodeId(container), container);
163    }
164
165    function handleSymbolAccessibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) {
166        if (symbolAccessibilityResult.accessibility === SymbolAccessibility.Accessible) {
167            // Add aliases back onto the possible imports list if they're not there so we can try them again with updated visibility info
168            if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) {
169                if (!lateMarkedStatements) {
170                    lateMarkedStatements = symbolAccessibilityResult.aliasesToMakeVisible;
171                }
172                else {
173                    for (const ref of symbolAccessibilityResult.aliasesToMakeVisible) {
174                        pushIfUnique(lateMarkedStatements, ref);
175                    }
176                }
177            }
178
179            // TODO: Do all these accessibility checks inside/after the first pass in the checker when declarations are enabled, if possible
180        }
181        else {
182            // Report error
183            const errorInfo = getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
184            if (errorInfo) {
185                if (errorInfo.typeName) {
186                    context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode,
187                        errorInfo.diagnosticMessage,
188                        getTextOfNode(errorInfo.typeName),
189                        symbolAccessibilityResult.errorSymbolName,
190                        symbolAccessibilityResult.errorModuleName));
191                }
192                else {
193                    context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode,
194                        errorInfo.diagnosticMessage,
195                        symbolAccessibilityResult.errorSymbolName,
196                        symbolAccessibilityResult.errorModuleName));
197                }
198                return true;
199            }
200        }
201        return false;
202    }
203
204    function trackExternalModuleSymbolOfImportTypeNode(symbol: Symbol) {
205        if (!isBundledEmit) {
206            (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
207        }
208    }
209
210    function trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) {
211        if (symbol.flags & SymbolFlags.TypeParameter) return false;
212        const issuedDiagnostic = handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
213        recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
214        return issuedDiagnostic;
215    }
216
217    function reportPrivateInBaseOfClassExpression(propertyName: string) {
218        if (errorNameNode || errorFallbackNode) {
219            context.addDiagnostic(
220                createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName));
221        }
222    }
223
224    function errorDeclarationNameWithFallback() {
225        return errorNameNode ? declarationNameToString(errorNameNode) :
226            errorFallbackNode && getNameOfDeclaration(errorFallbackNode) ? declarationNameToString(getNameOfDeclaration(errorFallbackNode)) :
227            errorFallbackNode && isExportAssignment(errorFallbackNode) ? errorFallbackNode.isExportEquals ? "export=" : "default" :
228            "(Missing)"; // same fallback declarationNameToString uses when node is zero-width (ie, nameless)
229    }
230
231    function reportInaccessibleUniqueSymbolError() {
232        if (errorNameNode || errorFallbackNode) {
233            context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary,
234                errorDeclarationNameWithFallback(),
235                "unique symbol"));
236        }
237    }
238
239    function reportCyclicStructureError() {
240        if (errorNameNode || errorFallbackNode) {
241            context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary,
242                errorDeclarationNameWithFallback()));
243        }
244    }
245
246    function reportInaccessibleThisError() {
247        if (errorNameNode || errorFallbackNode) {
248            context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary,
249                errorDeclarationNameWithFallback(),
250                "this"));
251        }
252    }
253
254    function reportLikelyUnsafeImportRequiredError(specifier: string) {
255        if (errorNameNode || errorFallbackNode) {
256            context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary,
257                errorDeclarationNameWithFallback(),
258                specifier));
259        }
260    }
261
262    function reportTruncationError() {
263        if (errorNameNode || errorFallbackNode) {
264            context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_this_node_exceeds_the_maximum_length_the_compiler_will_serialize_An_explicit_type_annotation_is_needed));
265        }
266    }
267
268    function reportNonlocalAugmentation(containingFile: SourceFile, parentSymbol: Symbol, symbol: Symbol) {
269        const primaryDeclaration = parentSymbol.declarations?.find(d => getSourceFileOfNode(d) === containingFile);
270        const augmentingDeclarations = filter(symbol.declarations, d => getSourceFileOfNode(d) !== containingFile);
271        if (primaryDeclaration && augmentingDeclarations) {
272            for (const augmentations of augmentingDeclarations) {
273                context.addDiagnostic(addRelatedInfo(
274                    createDiagnosticForNode(augmentations, Diagnostics.Declaration_augments_declaration_in_another_file_This_cannot_be_serialized),
275                    createDiagnosticForNode(primaryDeclaration, Diagnostics.This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file)
276                ));
277            }
278        }
279    }
280
281    function reportNonSerializableProperty(propertyName: string) {
282        if (errorNameNode || errorFallbackNode) {
283            context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_type_of_this_node_cannot_be_serialized_because_its_property_0_cannot_be_serialized, propertyName));
284        }
285    }
286
287    function reportImportTypeNodeResolutionModeOverride() {
288        if (!isNightly() && (errorNameNode || errorFallbackNode)) {
289            context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_type_of_this_expression_cannot_be_named_without_a_resolution_mode_assertion_which_is_an_unstable_feature_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next));
290        }
291    }
292
293    function transformDeclarationsForJS(sourceFile: SourceFile, bundled?: boolean) {
294        const oldDiag = getSymbolAccessibilityDiagnostic;
295        getSymbolAccessibilityDiagnostic = (s) => (s.errorNode && canProduceDiagnostics(s.errorNode) ? createGetSymbolAccessibilityDiagnosticForNode(s.errorNode)(s) : ({
296            diagnosticMessage: s.errorModuleName
297                ? Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit
298                : Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit,
299            errorNode: s.errorNode || sourceFile
300        }));
301        const result = resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, symbolTracker, bundled);
302        getSymbolAccessibilityDiagnostic = oldDiag;
303        return result;
304    }
305
306    function transformRoot(node: Bundle): Bundle;
307    function transformRoot(node: SourceFile): SourceFile;
308    function transformRoot(node: SourceFile | Bundle): SourceFile | Bundle;
309    function transformRoot(node: SourceFile | Bundle) {
310        if (node.kind === SyntaxKind.SourceFile && node.isDeclarationFile) {
311            return node;
312        }
313
314        if (node.kind === SyntaxKind.Bundle) {
315            isBundledEmit = true;
316            refs = new Map();
317            libs = new Map();
318            let hasNoDefaultLib = false;
319            const bundle = factory.createBundle(map(node.sourceFiles,
320                sourceFile => {
321                    if (sourceFile.isDeclarationFile) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217
322                    hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib;
323                    currentSourceFile = sourceFile;
324                    enclosingDeclaration = sourceFile;
325                    lateMarkedStatements = undefined;
326                    suppressNewDiagnosticContexts = false;
327                    lateStatementReplacementMap = new Map();
328                    getSymbolAccessibilityDiagnostic = throwDiagnostic;
329                    needsScopeFixMarker = false;
330                    resultHasScopeMarker = false;
331                    collectReferences(sourceFile, refs);
332                    collectLibs(sourceFile, libs);
333                    if (isExternalOrCommonJsModule(sourceFile) || isJsonSourceFile(sourceFile)) {
334                        resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
335                        needsDeclare = false;
336                        const statements = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements);
337                        const newFile = factory.updateSourceFile(sourceFile, [factory.createModuleDeclaration(
338                            [factory.createModifier(SyntaxKind.DeclareKeyword)],
339                            factory.createStringLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)),
340                            factory.createModuleBlock(setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements))
341                        )], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
342                        return newFile;
343                    }
344                    needsDeclare = true;
345                    const updated = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements);
346                    return factory.updateSourceFile(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
347                }
348            ), mapDefined(node.prepends, prepend => {
349                if (prepend.kind === SyntaxKind.InputFiles) {
350                    const sourceFile = createUnparsedSourceFile(prepend, "dts", stripInternal);
351                    hasNoDefaultLib = hasNoDefaultLib || !!sourceFile.hasNoDefaultLib;
352                    collectReferences(sourceFile, refs);
353                    recordTypeReferenceDirectivesIfNecessary(map(sourceFile.typeReferenceDirectives, ref => [ref.fileName, ref.resolutionMode]));
354                    collectLibs(sourceFile, libs);
355                    return sourceFile;
356                }
357                return prepend;
358            }));
359            bundle.syntheticFileReferences = [];
360            bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
361            bundle.syntheticLibReferences = getLibReferences();
362            bundle.hasNoDefaultLib = hasNoDefaultLib;
363            const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
364            const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath);
365            refs.forEach(referenceVisitor);
366            return bundle;
367        }
368
369        // Single source file
370        needsDeclare = true;
371        needsScopeFixMarker = false;
372        resultHasScopeMarker = false;
373        enclosingDeclaration = node;
374        currentSourceFile = node;
375        getSymbolAccessibilityDiagnostic = throwDiagnostic;
376        isBundledEmit = false;
377        resultHasExternalModuleIndicator = false;
378        suppressNewDiagnosticContexts = false;
379        lateMarkedStatements = undefined;
380        lateStatementReplacementMap = new Map();
381        necessaryTypeReferences = undefined;
382        refs = collectReferences(currentSourceFile, new Map());
383        libs = collectLibs(currentSourceFile, new Map());
384        const references: FileReference[] = [];
385        const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
386        const referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
387        let combinedStatements: NodeArray<Statement>;
388        if (isSourceFileJS(currentSourceFile)) {
389            combinedStatements = factory.createNodeArray(transformDeclarationsForJS(node));
390            refs.forEach(referenceVisitor);
391            emittedImports = filter(combinedStatements, isAnyImportSyntax);
392        }
393        else {
394            const statements = visitNodes(node.statements, visitDeclarationStatements);
395            combinedStatements = setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
396            refs.forEach(referenceVisitor);
397            emittedImports = filter(combinedStatements, isAnyImportSyntax);
398            if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
399                combinedStatements = setTextRange(factory.createNodeArray([...combinedStatements, createEmptyExports(factory)]), combinedStatements);
400            }
401        }
402        const updated = factory.updateSourceFile(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
403        updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
404        return updated;
405
406        function getLibReferences() {
407            return map(arrayFrom(libs.keys()), lib => ({ fileName: lib, pos: -1, end: -1 }));
408        }
409
410        function getFileReferencesForUsedTypeReferences() {
411            return necessaryTypeReferences ? mapDefined(arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForSpecifierModeTuple) : [];
412        }
413
414        function getFileReferenceForSpecifierModeTuple([typeName, mode]: [specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined]): FileReference | undefined {
415            // Elide type references for which we have imports
416            if (emittedImports) {
417                for (const importStatement of emittedImports) {
418                    if (isImportEqualsDeclaration(importStatement) && isExternalModuleReference(importStatement.moduleReference)) {
419                        const expr = importStatement.moduleReference.expression;
420                        if (isStringLiteralLike(expr) && expr.text === typeName) {
421                            return undefined;
422                        }
423                    }
424                    else if (isImportDeclaration(importStatement) && isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) {
425                        return undefined;
426                    }
427                }
428            }
429            return { fileName: typeName, pos: -1, end: -1, ...(mode ? { resolutionMode: mode } : undefined) };
430        }
431
432        function mapReferencesIntoArray(references: FileReference[], outputFilePath: string): (file: SourceFile) => void {
433            return file => {
434                let declFileName: string;
435                if (file.isDeclarationFile) { // Neither decl files or js should have their refs changed
436                    declFileName = file.fileName;
437                }
438                else {
439                    if (isBundledEmit && contains((node as Bundle).sourceFiles, file)) return; // Omit references to files which are being merged
440                    const paths = getOutputPathsFor(file, host, /*forceDtsPaths*/ true);
441                    declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName;
442                }
443
444                if (declFileName) {
445                    const specifier = moduleSpecifiers.getModuleSpecifier(
446                        options,
447                        currentSourceFile,
448                        toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName),
449                        toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName),
450                        host,
451                    );
452                    if (!pathIsRelative(specifier)) {
453                        // If some compiler option/symlink/whatever allows access to the file containing the ambient module declaration
454                        // via a non-relative name, emit a type reference directive to that non-relative name, rather than
455                        // a relative path to the declaration file
456                        recordTypeReferenceDirectivesIfNecessary([[specifier, /*mode*/ undefined]]);
457                        return;
458                    }
459
460                    let fileName = getRelativePathToDirectoryOrUrl(
461                        outputFilePath,
462                        declFileName,
463                        host.getCurrentDirectory(),
464                        host.getCanonicalFileName,
465                        /*isAbsolutePathAnUrl*/ false
466                    );
467                    if (startsWith(fileName, "./") && hasExtension(fileName)) {
468                        fileName = fileName.substring(2);
469                    }
470
471                    // omit references to files from node_modules or oh_modules (npm may disambiguate module
472                    // references when installing this package, making the path is unreliable).
473                    if (isNodeModulesReference(fileName) || (isOhpm(options.packageManagerType) && isOHModulesReference(fileName))) {
474                        return;
475                    }
476
477                    references.push({ pos: -1, end: -1, fileName });
478                }
479            };
480        }
481    }
482
483    function isNodeModulesReference(fileName: string): boolean {
484        return startsWith(fileName, "node_modules/") || pathContainsNodeModules(fileName);
485    }
486
487    function collectReferences(sourceFile: SourceFile | UnparsedSource, ret: ESMap<NodeId, SourceFile>) {
488        if (noResolve || (!isUnparsedSource(sourceFile) && isSourceFileJS(sourceFile))) return ret;
489        forEach(sourceFile.referencedFiles, f => {
490            const elem = host.getSourceFileFromReference(sourceFile, f);
491            if (elem) {
492                ret.set(getOriginalNodeId(elem), elem);
493            }
494        });
495        return ret;
496    }
497
498    function collectLibs(sourceFile: SourceFile | UnparsedSource, ret: ESMap<string, boolean>) {
499        forEach(sourceFile.libReferenceDirectives, ref => {
500            const lib = host.getLibFileFromReference(ref);
501            if (lib) {
502                ret.set(toFileNameLowerCase(ref.fileName), true);
503            }
504        });
505        return ret;
506    }
507
508    function filterBindingPatternInitializersAndRenamings(name: BindingName) {
509        if (name.kind === SyntaxKind.Identifier) {
510            return name;
511        }
512        else {
513            if (name.kind === SyntaxKind.ArrayBindingPattern) {
514                return factory.updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement));
515            }
516            else {
517                return factory.updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement));
518            }
519        }
520
521        function visitBindingElement<T extends ArrayBindingElement>(elem: T): T;
522        function visitBindingElement(elem: ArrayBindingElement): ArrayBindingElement {
523            if (elem.kind === SyntaxKind.OmittedExpression) {
524                return elem;
525            }
526            if (elem.propertyName && isIdentifier(elem.propertyName) && isIdentifier(elem.name) && !elem.symbol.isReferenced) {
527               // Unnecessary property renaming is forbidden in types, so remove renaming
528                return factory.updateBindingElement(
529                    elem,
530                    elem.dotDotDotToken,
531                    /* propertyName */ undefined,
532                    elem.propertyName,
533                    shouldPrintWithInitializer(elem) ? elem.initializer : undefined
534                );
535            }
536            return factory.updateBindingElement(
537                elem,
538                elem.dotDotDotToken,
539                elem.propertyName,
540                filterBindingPatternInitializersAndRenamings(elem.name),
541                shouldPrintWithInitializer(elem) ? elem.initializer : undefined
542            );
543        }
544    }
545
546    function ensureParameter(p: ParameterDeclaration, modifierMask?: ModifierFlags, type?: TypeNode): ParameterDeclaration {
547        let oldDiag: typeof getSymbolAccessibilityDiagnostic | undefined;
548        if (!suppressNewDiagnosticContexts) {
549            oldDiag = getSymbolAccessibilityDiagnostic;
550            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p);
551        }
552        const newParam = factory.updateParameterDeclaration(
553            p,
554            maskModifiers(p, modifierMask),
555            p.dotDotDotToken,
556            filterBindingPatternInitializersAndRenamings(p.name),
557            resolver.isOptionalParameter(p) ? (p.questionToken || factory.createToken(SyntaxKind.QuestionToken)) : undefined,
558            ensureType(p, type || p.type, /*ignorePrivate*/ true), // Ignore private param props, since this type is going straight back into a param
559            ensureNoInitializer(p)
560        );
561        if (!suppressNewDiagnosticContexts) {
562            getSymbolAccessibilityDiagnostic = oldDiag!;
563        }
564        return newParam;
565    }
566
567    function shouldPrintWithInitializer(node: Node) {
568        return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safe
569    }
570
571    function ensureNoInitializer(node: CanHaveLiteralInitializer) {
572        if (shouldPrintWithInitializer(node)) {
573            return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe
574        }
575        return undefined;
576    }
577
578    type HasInferredType =
579        | FunctionDeclaration
580        | MethodDeclaration
581        | GetAccessorDeclaration
582        | SetAccessorDeclaration
583        | BindingElement
584        | ConstructSignatureDeclaration
585        | VariableDeclaration
586        | MethodSignature
587        | CallSignatureDeclaration
588        | ParameterDeclaration
589        | PropertyDeclaration
590        | AnnotationPropertyDeclaration
591        | PropertySignature;
592
593    function ensureType(node: HasInferredType, type: TypeNode | undefined, ignorePrivate?: boolean): TypeNode | undefined {
594        if (!ignorePrivate && hasEffectiveModifier(node, ModifierFlags.Private)) {
595            // Private nodes emit no types (except private parameter properties, whose parameter types are actually visible)
596            return;
597        }
598        if (shouldPrintWithInitializer(node)) {
599            // Literal const declarations will have an initializer ensured rather than a type
600            return;
601        }
602        if (type !== undefined && isTypeReferenceNode(type) && type.typeName.virtual) {
603            return;
604        }
605        const shouldUseResolverType = node.kind === SyntaxKind.Parameter &&
606            (resolver.isRequiredInitializedParameter(node) ||
607                resolver.isOptionalUninitializedParameterProperty(node));
608        if (type && !shouldUseResolverType) {
609            return visitNode(type, visitDeclarationSubtree);
610        }
611        if (!getParseTreeNode(node)) {
612            return type ? visitNode(type, visitDeclarationSubtree) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
613        }
614        if (node.kind === SyntaxKind.SetAccessor) {
615            // Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now
616            // (The inferred type here will be void, but the old declaration emitter printed `any`, so this replicates that)
617            return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
618        }
619        errorNameNode = node.name;
620        let oldDiag: typeof getSymbolAccessibilityDiagnostic;
621        if (!suppressNewDiagnosticContexts) {
622            oldDiag = getSymbolAccessibilityDiagnostic;
623            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(node);
624        }
625        if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) {
626            return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
627        }
628        if (node.kind === SyntaxKind.Parameter
629            || node.kind === SyntaxKind.PropertyDeclaration
630            || node.kind === SyntaxKind.PropertySignature
631            || node.kind === SyntaxKind.AnnotationPropertyDeclaration) {
632            if (isPropertySignature(node) || !node.initializer) return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType));
633            return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType) || resolver.createTypeOfExpression(node.initializer, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
634        }
635        return cleanup(resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
636
637        function cleanup(returnValue: TypeNode | undefined) {
638            errorNameNode = undefined;
639            if (!suppressNewDiagnosticContexts) {
640                getSymbolAccessibilityDiagnostic = oldDiag;
641            }
642            return returnValue || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
643        }
644    }
645
646    function isDeclarationAndNotVisible(node: NamedDeclaration) {
647        node = getParseTreeNode(node) as NamedDeclaration;
648        switch (node.kind) {
649            case SyntaxKind.FunctionDeclaration:
650            case SyntaxKind.ModuleDeclaration:
651            case SyntaxKind.InterfaceDeclaration:
652            case SyntaxKind.ClassDeclaration:
653            case SyntaxKind.StructDeclaration:
654            case SyntaxKind.TypeAliasDeclaration:
655            case SyntaxKind.EnumDeclaration:
656            case SyntaxKind.AnnotationDeclaration:
657                return !resolver.isDeclarationVisible(node);
658            // The following should be doing their own visibility checks based on filtering their members
659            case SyntaxKind.VariableDeclaration:
660                return !getBindingNameVisible(node as VariableDeclaration);
661            case SyntaxKind.ImportEqualsDeclaration:
662            case SyntaxKind.ImportDeclaration:
663            case SyntaxKind.ExportDeclaration:
664            case SyntaxKind.ExportAssignment:
665                return false;
666            case SyntaxKind.ClassStaticBlockDeclaration:
667                return true;
668        }
669        return false;
670    }
671
672    // If the ExpandoFunctionDeclaration have multiple overloads, then we only need to emit properties for the last one.
673    function shouldEmitFunctionProperties(input: FunctionDeclaration) {
674        if (input.body) {
675            return true;
676        }
677
678        const overloadSignatures = input.symbol.declarations?.filter(decl => isFunctionDeclaration(decl) && !decl.body);
679        return !overloadSignatures || overloadSignatures.indexOf(input) === overloadSignatures.length - 1;
680    }
681
682    function getBindingNameVisible(elem: BindingElement | VariableDeclaration | OmittedExpression): boolean {
683        if (isOmittedExpression(elem)) {
684            return false;
685        }
686        if (isBindingPattern(elem.name)) {
687            // If any child binding pattern element has been marked visible (usually by collect linked aliases), then this is visible
688            return some(elem.name.elements, getBindingNameVisible);
689        }
690        else {
691            return resolver.isDeclarationVisible(elem);
692        }
693    }
694
695    function updateParamsList(node: Node, params: NodeArray<ParameterDeclaration>, modifierMask?: ModifierFlags) {
696        if (hasEffectiveModifier(node, ModifierFlags.Private)) {
697            return undefined!; // TODO: GH#18217
698        }
699        const newParams = map(params, p => ensureParameter(p, modifierMask));
700        if (!newParams) {
701            return undefined!; // TODO: GH#18217
702        }
703        return factory.createNodeArray(newParams, params.hasTrailingComma);
704    }
705
706    function updateAccessorParamsList(input: AccessorDeclaration, isPrivate: boolean) {
707        let newParams: ParameterDeclaration[] | undefined;
708        if (!isPrivate) {
709            const thisParameter = getThisParameter(input);
710            if (thisParameter) {
711                newParams = [ensureParameter(thisParameter)];
712            }
713        }
714        if (isSetAccessorDeclaration(input)) {
715            let newValueParameter: ParameterDeclaration | undefined;
716            if (!isPrivate) {
717                const valueParameter = getSetAccessorValueParameter(input);
718                if (valueParameter) {
719                    const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
720                    newValueParameter = ensureParameter(valueParameter, /*modifierMask*/ undefined, accessorType);
721                }
722            }
723            if (!newValueParameter) {
724                newValueParameter = factory.createParameterDeclaration(
725                    /*modifiers*/ undefined,
726                    /*dotDotDotToken*/ undefined,
727                    "value"
728                );
729            }
730            newParams = append(newParams, newValueParameter);
731        }
732        return factory.createNodeArray(newParams || emptyArray);
733    }
734
735    function ensureTypeParams(node: Node, params: NodeArray<TypeParameterDeclaration> | undefined) {
736        return hasEffectiveModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree);
737    }
738
739    function isEnclosingDeclaration(node: Node) {
740        return isSourceFile(node)
741            || isTypeAliasDeclaration(node)
742            || isModuleDeclaration(node)
743            || isClassDeclaration(node)
744            || isStructDeclaration(node)
745            || isAnnotationDeclaration(node)
746            || isInterfaceDeclaration(node)
747            || isFunctionLike(node)
748            || isIndexSignatureDeclaration(node)
749            || isMappedTypeNode(node);
750    }
751
752    function checkEntityNameVisibility(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node) {
753        const visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration);
754        handleSymbolAccessibilityError(visibilityResult);
755        recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
756    }
757
758    function preserveJsDoc<T extends Node>(updated: T, original: Node): T {
759        if (hasJSDocNodes(updated) && hasJSDocNodes(original)) {
760            updated.jsDoc = original.jsDoc;
761        }
762        return setCommentRange(updated, getCommentRange(original));
763    }
764
765    function rewriteModuleSpecifier<T extends Node>(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode, input: T | undefined): T | StringLiteral {
766        if (!input) return undefined!; // TODO: GH#18217
767        resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== SyntaxKind.ModuleDeclaration && parent.kind !== SyntaxKind.ImportType);
768        if (isStringLiteralLike(input)) {
769            if (isBundledEmit) {
770                const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
771                if (newName) {
772                    return factory.createStringLiteral(newName);
773                }
774            }
775            else {
776                const symbol = resolver.getSymbolOfExternalModuleSpecifier(input);
777                if (symbol) {
778                    (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
779                }
780            }
781        }
782        return input;
783    }
784
785    function transformImportEqualsDeclaration(decl: ImportEqualsDeclaration) {
786        if (!resolver.isDeclarationVisible(decl)) return;
787        if (decl.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
788            // Rewrite external module names if necessary
789            const specifier = getExternalModuleImportEqualsDeclarationExpression(decl);
790            return factory.updateImportEqualsDeclaration(
791                decl,
792                decl.modifiers,
793                decl.isTypeOnly,
794                decl.name,
795                factory.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier))
796            );
797        }
798        else {
799            const oldDiag = getSymbolAccessibilityDiagnostic;
800            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(decl);
801            checkEntityNameVisibility(decl.moduleReference, enclosingDeclaration);
802            getSymbolAccessibilityDiagnostic = oldDiag;
803            return decl;
804        }
805    }
806
807    function transformImportDeclaration(decl: ImportDeclaration) {
808        if (!decl.importClause) {
809            // import "mod" - possibly needed for side effects? (global interface patches, module augmentations, etc)
810            return factory.updateImportDeclaration(
811                decl,
812                decl.modifiers,
813                decl.importClause,
814                rewriteModuleSpecifier(decl, decl.moduleSpecifier),
815                getResolutionModeOverrideForClauseInNightly(decl.assertClause)
816            );
817        }
818        // The `importClause` visibility corresponds to the default's visibility.
819        const visibleDefaultBinding = decl.importClause && decl.importClause.name && resolver.isDeclarationVisible(decl.importClause) ? decl.importClause.name : undefined;
820        if (!decl.importClause.namedBindings) {
821            // No named bindings (either namespace or list), meaning the import is just default or should be elided
822            return visibleDefaultBinding && factory.updateImportDeclaration(decl, decl.modifiers, factory.updateImportClause(
823                decl.importClause,
824                decl.importClause.isTypeOnly,
825                visibleDefaultBinding,
826                /*namedBindings*/ undefined,
827            ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause));
828        }
829        if (decl.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
830            // Namespace import (optionally with visible default)
831            const namedBindings = resolver.isDeclarationVisible(decl.importClause.namedBindings) ? decl.importClause.namedBindings : /*namedBindings*/ undefined;
832            return visibleDefaultBinding || namedBindings ? factory.updateImportDeclaration(decl, decl.modifiers, factory.updateImportClause(
833                decl.importClause,
834                decl.importClause.isTypeOnly,
835                visibleDefaultBinding,
836                namedBindings,
837            ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)) : undefined;
838        }
839        // Named imports (optionally with visible default)
840        const bindingList = mapDefined(decl.importClause.namedBindings.elements, b => resolver.isDeclarationVisible(b) ? b : undefined);
841        if ((bindingList && bindingList.length) || visibleDefaultBinding) {
842            return factory.updateImportDeclaration(
843                decl,
844                decl.modifiers,
845                factory.updateImportClause(
846                    decl.importClause,
847                    decl.importClause.isTypeOnly,
848                    visibleDefaultBinding,
849                    bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined,
850                ),
851                rewriteModuleSpecifier(decl, decl.moduleSpecifier),
852                getResolutionModeOverrideForClauseInNightly(decl.assertClause)
853            );
854        }
855        // Augmentation of export depends on import
856        if (resolver.isImportRequiredByAugmentation(decl)) {
857            if (isolatedDeclarations) {
858                context.addDiagnostic(createDiagnosticForNode(decl, Diagnostics.Declaration_emit_for_this_file_requires_preserving_this_import_for_augmentations_This_is_not_supported_with_isolatedDeclarations));
859            }
860            return factory.updateImportDeclaration(
861                decl,
862                decl.modifiers,
863                /*importClause*/ undefined,
864                rewriteModuleSpecifier(decl, decl.moduleSpecifier),
865                getResolutionModeOverrideForClauseInNightly(decl.assertClause)
866            );
867        }
868        // Nothing visible
869    }
870
871    function getResolutionModeOverrideForClauseInNightly(assertClause: AssertClause | undefined) {
872        const mode = getResolutionModeOverrideForClause(assertClause);
873        if (mode !== undefined) {
874            if (!isNightly()) {
875                context.addDiagnostic(createDiagnosticForNode(assertClause!, Diagnostics.resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next));
876            }
877            return assertClause;
878        }
879        return undefined;
880    }
881
882    function transformAndReplaceLatePaintedStatements(statements: NodeArray<Statement>): NodeArray<Statement> {
883        // This is a `while` loop because `handleSymbolAccessibilityError` can see additional import aliases marked as visible during
884        // error handling which must now be included in the output and themselves checked for errors.
885        // For example:
886        // ```
887        // module A {
888        //   export module Q {}
889        //   import B = Q;
890        //   import C = B;
891        //   export import D = C;
892        // }
893        // ```
894        // In such a scenario, only Q and D are initially visible, but we don't consider imports as private names - instead we say they if they are referenced they must
895        // be recorded. So while checking D's visibility we mark C as visible, then we must check C which in turn marks B, completing the chain of
896        // dependent imports and allowing a valid declaration file output. Today, this dependent alias marking only happens for internal import aliases.
897        while (length(lateMarkedStatements)) {
898            const i = lateMarkedStatements!.shift()!;
899            if (!isLateVisibilityPaintedStatement(i)) {
900                return Debug.fail(`Late replaced statement was found which is not handled by the declaration transformer!: ${Debug.formatSyntaxKind((i as Node).kind)}`);
901            }
902            const priorNeedsDeclare = needsDeclare;
903            needsDeclare = i.parent && isSourceFile(i.parent) && !(isExternalModule(i.parent) && isBundledEmit);
904            const result = transformTopLevelDeclaration(i);
905            needsDeclare = priorNeedsDeclare;
906            lateStatementReplacementMap.set(getOriginalNodeId(i), result);
907        }
908
909        // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list
910        // (and remove them from the set to examine for outter declarations)
911        return visitNodes(statements, visitLateVisibilityMarkedStatements);
912
913        function visitLateVisibilityMarkedStatements(statement: Statement) {
914            if (isLateVisibilityPaintedStatement(statement)) {
915                const key = getOriginalNodeId(statement);
916                if (lateStatementReplacementMap.has(key)) {
917                    const result = lateStatementReplacementMap.get(key);
918                    lateStatementReplacementMap.delete(key);
919                    if (result) {
920                        if (isArray(result) ? some(result, needsScopeMarker) : needsScopeMarker(result)) {
921                            // Top-level declarations in .d.ts files are always considered exported even without a modifier unless there's an export assignment or specifier
922                            needsScopeFixMarker = true;
923                        }
924                        if (isSourceFile(statement.parent) && (isArray(result) ? some(result, isExternalModuleIndicator) : isExternalModuleIndicator(result))) {
925                            resultHasExternalModuleIndicator = true;
926                        }
927                    }
928                    return result;
929                }
930            }
931            return statement;
932        }
933    }
934
935    function checkAnnotationVisibilityByDecorator(input: readonly Decorator[]): void {
936        forEach(input, (decorator) => {
937            if (!isAnnotation(decorator)) {
938                return;
939            }
940            if (isCallExpression(decorator.expression)) {
941                // @Anno({})
942                checkEntityNameVisibility((decorator.expression.expression) as Identifier, enclosingDeclaration);
943            } else if (isIdentifier(decorator.expression)) {
944                // @Anno
945                checkEntityNameVisibility((decorator.expression) as Identifier, enclosingDeclaration);
946            }
947        });
948    }
949
950    function visitDeclarationSubtree(input: Node): VisitResult<Node> {
951        if (shouldStripInternal(input)) return;
952        if (isDeclaration(input)) {
953            if (isDeclarationAndNotVisible(input)) return;
954            if (hasDynamicName(input) && !resolver.isLateBound(getParseTreeNode(input) as Declaration)) {
955                return;
956            }
957        }
958
959        // Elide implementation signatures from overload sets
960        if (isFunctionLike(input) && resolver.isImplementationOfOverload(input)) return;
961
962        // Elide semicolon class statements
963        if (isSemicolonClassElement(input)) return;
964
965        let previousEnclosingDeclaration: typeof enclosingDeclaration;
966        if (isEnclosingDeclaration(input)) {
967            previousEnclosingDeclaration = enclosingDeclaration;
968            enclosingDeclaration = input as Declaration;
969        }
970        const oldDiag = getSymbolAccessibilityDiagnostic;
971
972        // Setup diagnostic-related flags before first potential `cleanup` call, otherwise
973        // We'd see a TDZ violation at runtime
974        const canProduceDiagnostic = canProduceDiagnostics(input);
975        const oldWithinObjectLiteralType = suppressNewDiagnosticContexts;
976        let shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === SyntaxKind.TypeLiteral || input.kind === SyntaxKind.MappedType) && input.parent.kind !== SyntaxKind.TypeAliasDeclaration);
977
978        // Emit methods which are private as properties with no type information
979        if (isMethodDeclaration(input) || isMethodSignature(input)) {
980            if (hasEffectiveModifier(input, ModifierFlags.Private)) {
981                if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input) return; // Elide all but the first overload
982                return cleanup(factory.createPropertyDeclaration(ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
983            }
984        }
985
986        if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
987            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input);
988        }
989
990        if (isTypeQueryNode(input)) {
991            checkEntityNameVisibility(input.exprName, enclosingDeclaration);
992        }
993
994        if (shouldEnterSuppressNewDiagnosticsContextContext) {
995            // We stop making new diagnostic contexts within object literal types. Unless it's an object type on the RHS of a type alias declaration. Then we do.
996            suppressNewDiagnosticContexts = true;
997        }
998
999        if (isProcessedComponent(input)) {
1000            switch (input.kind) {
1001                case SyntaxKind.ExpressionWithTypeArguments: {
1002                    if ((isEntityName(input.expression) || isEntityNameExpression(input.expression))) {
1003                        checkEntityNameVisibility(input.expression, enclosingDeclaration);
1004                    }
1005                    const node = visitEachChild(input, visitDeclarationSubtree, context);
1006                    return cleanup(factory.updateExpressionWithTypeArguments(node, node.expression, node.typeArguments));
1007                }
1008                case SyntaxKind.TypeReference: {
1009                    checkEntityNameVisibility(input.typeName, enclosingDeclaration);
1010                    const node = visitEachChild(input, visitDeclarationSubtree, context);
1011                    return cleanup(factory.updateTypeReferenceNode(node, node.typeName, node.typeArguments));
1012                }
1013                case SyntaxKind.ConstructSignature:
1014                    return cleanup(factory.updateConstructSignature(
1015                        input,
1016                        ensureTypeParams(input, input.typeParameters),
1017                        updateParamsList(input, input.parameters),
1018                        ensureType(input, input.type)
1019                    ));
1020                case SyntaxKind.Constructor: {
1021                    // A constructor declaration may not have a type annotation
1022                    const ctor = factory.createConstructorDeclaration(
1023                        /*modifiers*/ ensureModifiers(input),
1024                        updateParamsList(input, input.parameters, ModifierFlags.None),
1025                        /*body*/ undefined
1026                    );
1027                    return cleanup(ctor);
1028                }
1029                case SyntaxKind.MethodDeclaration: {
1030                    if (isPrivateIdentifier(input.name)) {
1031                        return cleanup(/*returnValue*/ undefined);
1032                    }
1033                    let reservedDecorators = concatenate(getReservedDecoratorsOfStructDeclaration(input, host), getAnnotations(input));
1034                    checkAnnotationVisibilityByDecorator(reservedDecorators);
1035                    const sig = factory.createMethodDeclaration(
1036                        concatenateDecoratorsAndModifiers(reservedDecorators, ensureModifiers(input)),
1037                        /*asteriskToken*/ undefined,
1038                        input.name,
1039                        input.questionToken,
1040                        inEtsStylesContext(input, host) ? undefined : ensureTypeParams(input, input.typeParameters),
1041                        updateParamsList(input, input.parameters),
1042                        ensureType(input, input.type),
1043                        /*body*/ undefined
1044                    );
1045                    return cleanup(sig);
1046                }
1047                case SyntaxKind.GetAccessor: {
1048                    if (isPrivateIdentifier(input.name)) {
1049                        return cleanup(/*returnValue*/ undefined);
1050                    }
1051                    const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
1052                    return cleanup(factory.updateGetAccessorDeclaration(
1053                        input,
1054                        ensureModifiers(input),
1055                        input.name,
1056                        updateAccessorParamsList(input, hasEffectiveModifier(input, ModifierFlags.Private)),
1057                        ensureType(input, accessorType),
1058                        /*body*/ undefined));
1059                }
1060                case SyntaxKind.SetAccessor: {
1061                    if (isPrivateIdentifier(input.name)) {
1062                        return cleanup(/*returnValue*/ undefined);
1063                    }
1064                    return cleanup(factory.updateSetAccessorDeclaration(
1065                        input,
1066                        ensureModifiers(input),
1067                        input.name,
1068                        updateAccessorParamsList(input, hasEffectiveModifier(input, ModifierFlags.Private)),
1069                        /*body*/ undefined));
1070                }
1071                case SyntaxKind.PropertyDeclaration:
1072                    if (isPrivateIdentifier(input.name)) {
1073                        return cleanup(/*returnValue*/ undefined);
1074                    }
1075                    let reservedDecorators = getReservedDecoratorsOfStructDeclaration(input, host);
1076
1077                    return cleanup(factory.updatePropertyDeclaration(
1078                        input,
1079                        concatenateDecoratorsAndModifiers(reservedDecorators, ensureModifiers(input)),
1080                        input.name,
1081                        input.questionToken,
1082                        ensureType(input, input.type),
1083                        ensureNoInitializer(input)
1084                    ));
1085                case SyntaxKind.AnnotationPropertyDeclaration:
1086                    return cleanup(factory.updateAnnotationPropertyDeclaration(
1087                        input,
1088                        input.name,
1089                        ensureType(input, input.type),
1090                        input.initializer,
1091                    ));
1092                case SyntaxKind.PropertySignature:
1093                    if (isPrivateIdentifier(input.name)) {
1094                        return cleanup(/*returnValue*/ undefined);
1095                    }
1096                    return cleanup(factory.updatePropertySignature(
1097                        input,
1098                        ensureModifiers(input),
1099                        input.name,
1100                        input.questionToken,
1101                        ensureType(input, input.type)
1102                    ));
1103                case SyntaxKind.MethodSignature: {
1104                    if (isPrivateIdentifier(input.name)) {
1105                        return cleanup(/*returnValue*/ undefined);
1106                    }
1107                    return cleanup(factory.updateMethodSignature(
1108                        input,
1109                        ensureModifiers(input),
1110                        input.name,
1111                        input.questionToken,
1112                        ensureTypeParams(input, input.typeParameters),
1113                        updateParamsList(input, input.parameters),
1114                        ensureType(input, input.type)
1115                    ));
1116                }
1117                case SyntaxKind.CallSignature: {
1118                    return cleanup(factory.updateCallSignature(
1119                        input,
1120                        ensureTypeParams(input, input.typeParameters),
1121                        updateParamsList(input, input.parameters),
1122                        ensureType(input, input.type)
1123                    ));
1124                }
1125                case SyntaxKind.IndexSignature: {
1126                    return cleanup(factory.updateIndexSignature(
1127                        input,
1128                        ensureModifiers(input),
1129                        updateParamsList(input, input.parameters),
1130                        visitNode(input.type, visitDeclarationSubtree) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
1131                    ));
1132                }
1133                case SyntaxKind.VariableDeclaration: {
1134                    if (isBindingPattern(input.name)) {
1135                        return recreateBindingPattern(input.name);
1136                    }
1137                    shouldEnterSuppressNewDiagnosticsContextContext = true;
1138                    suppressNewDiagnosticContexts = true; // Variable declaration types also suppress new diagnostic contexts, provided the contexts wouldn't be made for binding pattern types
1139                    return cleanup(factory.updateVariableDeclaration(input, input.name, /*exclamationToken*/ undefined, ensureType(input, input.type), ensureNoInitializer(input)));
1140                }
1141                case SyntaxKind.TypeParameter: {
1142                    if (isPrivateMethodTypeParameter(input) && (input.default || input.constraint)) {
1143                        return cleanup(factory.updateTypeParameterDeclaration(input, input.modifiers, input.name, /*constraint*/ undefined, /*defaultType*/ undefined));
1144                    }
1145                    return cleanup(visitEachChild(input, visitDeclarationSubtree, context));
1146                }
1147                case SyntaxKind.ConditionalType: {
1148                    // We have to process conditional types in a special way because for visibility purposes we need to push a new enclosingDeclaration
1149                    // just for the `infer` types in the true branch. It's an implicit declaration scope that only applies to _part_ of the type.
1150                    const checkType = visitNode(input.checkType, visitDeclarationSubtree);
1151                    const extendsType = visitNode(input.extendsType, visitDeclarationSubtree);
1152                    const oldEnclosingDecl = enclosingDeclaration;
1153                    enclosingDeclaration = input.trueType;
1154                    const trueType = visitNode(input.trueType, visitDeclarationSubtree);
1155                    enclosingDeclaration = oldEnclosingDecl;
1156                    const falseType = visitNode(input.falseType, visitDeclarationSubtree);
1157                    return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType));
1158                }
1159                case SyntaxKind.FunctionType: {
1160                    return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree)));
1161                }
1162                case SyntaxKind.ConstructorType: {
1163                    return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree)));
1164                }
1165                case SyntaxKind.ImportType: {
1166                    if (!isLiteralImportTypeNode(input)) return cleanup(input);
1167                    return cleanup(factory.updateImportTypeNode(
1168                        input,
1169                        factory.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)),
1170                        input.assertions,
1171                        input.qualifier,
1172                        visitNodes(input.typeArguments, visitDeclarationSubtree, isTypeNode),
1173                        input.isTypeOf
1174                    ));
1175                }
1176                default: Debug.assertNever(input, `Attempted to process unhandled node kind: ${Debug.formatSyntaxKind((input as Node).kind)}`);
1177            }
1178        }
1179
1180        if (isTupleTypeNode(input) && (getLineAndCharacterOfPosition(currentSourceFile, input.pos).line === getLineAndCharacterOfPosition(currentSourceFile, input.end).line)) {
1181            setEmitFlags(input, EmitFlags.SingleLine);
1182        }
1183
1184        return cleanup(visitEachChild(input, visitDeclarationSubtree, context));
1185
1186        function cleanup<T extends Node>(returnValue: T | undefined): T | undefined {
1187            if (returnValue && canProduceDiagnostic && hasDynamicName(input as Declaration)) {
1188                checkName(input);
1189            }
1190            if (isEnclosingDeclaration(input)) {
1191                enclosingDeclaration = previousEnclosingDeclaration;
1192            }
1193            if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
1194                getSymbolAccessibilityDiagnostic = oldDiag;
1195            }
1196            if (shouldEnterSuppressNewDiagnosticsContextContext) {
1197                suppressNewDiagnosticContexts = oldWithinObjectLiteralType;
1198            }
1199            if (returnValue === input) {
1200                return returnValue;
1201            }
1202            return returnValue && setOriginalNode(preserveJsDoc(returnValue, input), input);
1203        }
1204    }
1205
1206    function isPrivateMethodTypeParameter(node: TypeParameterDeclaration) {
1207        return node.parent.kind === SyntaxKind.MethodDeclaration && hasEffectiveModifier(node.parent, ModifierFlags.Private);
1208    }
1209
1210    function visitDeclarationStatements(input: Node): VisitResult<Node> {
1211        if (!isPreservedDeclarationStatement(input)) {
1212            // return undefined for unmatched kinds to omit them from the tree
1213            return;
1214        }
1215        if (shouldStripInternal(input)) return;
1216
1217        switch (input.kind) {
1218            case SyntaxKind.ExportDeclaration: {
1219                if (isSourceFile(input.parent)) {
1220                    resultHasExternalModuleIndicator = true;
1221                }
1222                resultHasScopeMarker = true;
1223                // Always visible if the parent node isn't dropped for being not visible
1224                // Rewrite external module names if necessary
1225                return factory.updateExportDeclaration(
1226                    input,
1227                    input.modifiers,
1228                    input.isTypeOnly,
1229                    input.exportClause,
1230                    rewriteModuleSpecifier(input, input.moduleSpecifier),
1231                    getResolutionModeOverrideForClause(input.assertClause) ? input.assertClause : undefined
1232                );
1233            }
1234            case SyntaxKind.ExportAssignment: {
1235                // Always visible if the parent node isn't dropped for being not visible
1236                if (isSourceFile(input.parent)) {
1237                    resultHasExternalModuleIndicator = true;
1238                }
1239                resultHasScopeMarker = true;
1240                if (input.expression.kind === SyntaxKind.Identifier) {
1241                    return input;
1242                }
1243                else {
1244                    const newId = factory.createUniqueName("_default", GeneratedIdentifierFlags.Optimistic);
1245                    getSymbolAccessibilityDiagnostic = () => ({
1246                        diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
1247                        errorNode: input
1248                    });
1249                    errorFallbackNode = input;
1250                    const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
1251                    errorFallbackNode = undefined;
1252                    const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const));
1253
1254                    preserveJsDoc(statement, input);
1255                    removeAllComments(input);
1256                    return [statement, factory.updateExportAssignment(input, input.modifiers, newId)];
1257                }
1258            }
1259        }
1260
1261        const result = transformTopLevelDeclaration(input);
1262        // Don't actually transform yet; just leave as original node - will be elided/swapped by late pass
1263        lateStatementReplacementMap.set(getOriginalNodeId(input), result);
1264        return input;
1265    }
1266
1267    function stripExportModifiers(statement: Statement): Statement {
1268        if (isImportEqualsDeclaration(statement) || hasEffectiveModifier(statement, ModifierFlags.Default) || !canHaveModifiers(statement)) {
1269            // `export import` statements should remain as-is, as imports are _not_ implicitly exported in an ambient namespace
1270            // Likewise, `export default` classes and the like and just be `default`, so we preserve their `export` modifiers, too
1271            return statement;
1272        }
1273
1274        const modifiers = factory.createModifiersFromModifierFlags(getEffectiveModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export));
1275        return factory.updateModifiers(statement, modifiers);
1276    }
1277
1278    function transformTopLevelDeclaration(input: LateVisibilityPaintedStatement) {
1279        if (lateMarkedStatements) {
1280            while (orderedRemoveItem(lateMarkedStatements, input));
1281        }
1282        if (shouldStripInternal(input)) return;
1283        switch (input.kind) {
1284            case SyntaxKind.ImportEqualsDeclaration: {
1285                return transformImportEqualsDeclaration(input);
1286            }
1287            case SyntaxKind.ImportDeclaration: {
1288                return transformImportDeclaration(input);
1289            }
1290        }
1291        if (isDeclaration(input) && isDeclarationAndNotVisible(input)) return;
1292
1293        // Elide implementation signatures from overload sets
1294        if (isFunctionLike(input) && resolver.isImplementationOfOverload(input)) return;
1295
1296        let previousEnclosingDeclaration: typeof enclosingDeclaration;
1297        if (isEnclosingDeclaration(input)) {
1298            previousEnclosingDeclaration = enclosingDeclaration;
1299            enclosingDeclaration = input as Declaration;
1300        }
1301
1302        const canProdiceDiagnostic = canProduceDiagnostics(input);
1303        const oldDiag = getSymbolAccessibilityDiagnostic;
1304        if (canProdiceDiagnostic) {
1305            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input as DeclarationDiagnosticProducing);
1306        }
1307
1308        const previousNeedsDeclare = needsDeclare;
1309        switch (input.kind) {
1310            case SyntaxKind.TypeAliasDeclaration: {
1311                needsDeclare = false;
1312                const clean = cleanup(factory.updateTypeAliasDeclaration(
1313                    input,
1314                    ensureModifiers(input),
1315                    input.name,
1316                    visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration),
1317                    visitNode(input.type, visitDeclarationSubtree, isTypeNode)
1318                ));
1319                // Default factory will set illegalDecorators in updateTypeAliasDeclaration, add extra set here to avoid abnormal case.
1320                if (isSendableFunctionOrType(input)) {
1321                    (clean as Mutable<TypeAliasDeclaration>).illegalDecorators = input.illegalDecorators;
1322                }
1323                needsDeclare = previousNeedsDeclare;
1324                return clean;
1325            }
1326            case SyntaxKind.InterfaceDeclaration: {
1327                return cleanup(factory.updateInterfaceDeclaration(
1328                    input,
1329                    ensureModifiers(input),
1330                    input.name,
1331                    ensureTypeParams(input, input.typeParameters),
1332                    transformHeritageClauses(input.heritageClauses),
1333                    visitNodes(input.members, visitDeclarationSubtree)
1334                ));
1335            }
1336            case SyntaxKind.FunctionDeclaration: {
1337                // Generators lose their generator-ness, excepting their return type
1338                const clean = cleanup(factory.updateFunctionDeclaration(
1339                    input,
1340                    ensureModifiers(input),
1341                    /*asteriskToken*/ undefined,
1342                    input.name,
1343                    inEtsStylesContext(input, host) ? undefined : ensureTypeParams(input, input.typeParameters),
1344                    updateParamsList(input, input.parameters),
1345                    ensureType(input, input.type),
1346                    /*body*/ undefined
1347                ));
1348                if (isSendableFunctionOrType(input)) {
1349                    (clean as Mutable<FunctionDeclaration>).illegalDecorators = input.illegalDecorators;
1350                }
1351                else if (isInEtsFile(input)) {
1352                    const reservedDecorators = getEffectiveDecorators(input.illegalDecorators, host);
1353                    (clean as Mutable<FunctionDeclaration>).illegalDecorators = factory.createNodeArray(reservedDecorators);
1354                }
1355                if (clean && resolver.isExpandoFunctionDeclaration(input) && shouldEmitFunctionProperties(input)) {
1356                    const props = resolver.getPropertiesOfContainerFunction(input);
1357                    // Use parseNodeFactory so it is usable as an enclosing declaration
1358                    const fakespace = parseNodeFactory.createModuleDeclaration(/*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), NodeFlags.Namespace);
1359                    setParent(fakespace, enclosingDeclaration as SourceFile | NamespaceDeclaration);
1360                    fakespace.locals = createSymbolTable(props);
1361                    fakespace.symbol = props[0].parent!;
1362                    const exportMappings: [Identifier, string][] = [];
1363                    let declarations: (VariableStatement | ExportDeclaration)[] = mapDefined(props, p => {
1364                        if (!p.valueDeclaration || !isPropertyAccessExpression(p.valueDeclaration)) {
1365                            return undefined; // TODO GH#33569: Handle element access expressions that created late bound names (rather than silently omitting them)
1366                        }
1367                        getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
1368                        const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, symbolTracker);
1369                        getSymbolAccessibilityDiagnostic = oldDiag;
1370                        const nameStr = unescapeLeadingUnderscores(p.escapedName);
1371                        const isNonContextualKeywordName = isStringANonContextualKeyword(nameStr);
1372                        const name = isNonContextualKeywordName ? factory.getGeneratedNameForNode(p.valueDeclaration) : factory.createIdentifier(nameStr);
1373                        if (isNonContextualKeywordName) {
1374                            exportMappings.push([name, nameStr]);
1375                        }
1376                        const varDecl = factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, /*initializer*/ undefined);
1377                        return factory.createVariableStatement(isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([varDecl]));
1378                    });
1379                    if (!exportMappings.length) {
1380                        declarations = mapDefined(declarations, declaration => factory.updateModifiers(declaration, ModifierFlags.None));
1381                    }
1382                    else {
1383                        declarations.push(factory.createExportDeclaration(
1384                            /*modifiers*/ undefined,
1385                            /*isTypeOnly*/ false,
1386                            factory.createNamedExports(map(exportMappings, ([gen, exp]) => {
1387                                return factory.createExportSpecifier(/*isTypeOnly*/ false, gen, exp);
1388                            }))
1389                        ));
1390                    }
1391                    const namespaceDecl = factory.createModuleDeclaration(ensureModifiers(input), input.name!, factory.createModuleBlock(declarations), NodeFlags.Namespace);
1392                    if (!hasEffectiveModifier(clean, ModifierFlags.Default)) {
1393                        return [clean, namespaceDecl];
1394                    }
1395
1396                    const modifiers = factory.createModifiersFromModifierFlags((getEffectiveModifierFlags(clean) & ~ModifierFlags.ExportDefault) | ModifierFlags.Ambient);
1397
1398                    const cleanDeclaration = factory.updateFunctionDeclaration(
1399                        clean,
1400                        modifiers,
1401                        /*asteriskToken*/ undefined,
1402                        clean.name,
1403                        clean.typeParameters,
1404                        clean.parameters,
1405                        clean.type,
1406                        /*body*/ undefined
1407                    );
1408                    if (isInEtsFile(input)) {
1409                        const reservedDecorators = getEffectiveDecorators(clean.illegalDecorators, host);
1410                        (cleanDeclaration as Mutable<FunctionDeclaration>).illegalDecorators = factory.createNodeArray(reservedDecorators);
1411                    }
1412                    const namespaceDeclaration = factory.updateModuleDeclaration(
1413                        namespaceDecl,
1414                        modifiers,
1415                        namespaceDecl.name,
1416                        namespaceDecl.body
1417                    );
1418
1419                    const exportDefaultDeclaration = factory.createExportAssignment(
1420                        /*modifiers*/ undefined,
1421                        /*isExportEquals*/ false,
1422                        namespaceDecl.name
1423                    );
1424
1425                    if (isSourceFile(input.parent)) {
1426                        resultHasExternalModuleIndicator = true;
1427                    }
1428                    resultHasScopeMarker = true;
1429
1430                    return [cleanDeclaration, namespaceDeclaration, exportDefaultDeclaration];
1431                }
1432                else {
1433                    return clean;
1434                }
1435            }
1436            case SyntaxKind.ModuleDeclaration: {
1437                needsDeclare = false;
1438                const inner = input.body;
1439                if (inner && inner.kind === SyntaxKind.ModuleBlock) {
1440                    const oldNeedsScopeFix = needsScopeFixMarker;
1441                    const oldHasScopeFix = resultHasScopeMarker;
1442                    resultHasScopeMarker = false;
1443                    needsScopeFixMarker = false;
1444                    const statements = visitNodes(inner.statements, visitDeclarationStatements);
1445                    let lateStatements = transformAndReplaceLatePaintedStatements(statements);
1446                    if (input.flags & NodeFlags.Ambient) {
1447                        needsScopeFixMarker = false; // If it was `declare`'d everything is implicitly exported already, ignore late printed "privates"
1448                    }
1449                    // With the final list of statements, there are 3 possibilities:
1450                    // 1. There's an export assignment or export declaration in the namespace - do nothing
1451                    // 2. Everything is exported and there are no export assignments or export declarations - strip all export modifiers
1452                    // 3. Some things are exported, some are not, and there's no marker - add an empty marker
1453                    if (!isGlobalScopeAugmentation(input) && !hasScopeMarker(lateStatements) && !resultHasScopeMarker) {
1454                        if (needsScopeFixMarker) {
1455                            lateStatements = factory.createNodeArray([...lateStatements, createEmptyExports(factory)]);
1456                        }
1457                        else {
1458                            lateStatements = visitNodes(lateStatements, stripExportModifiers);
1459                        }
1460                    }
1461                    const body = factory.updateModuleBlock(inner, lateStatements);
1462                    needsDeclare = previousNeedsDeclare;
1463                    needsScopeFixMarker = oldNeedsScopeFix;
1464                    resultHasScopeMarker = oldHasScopeFix;
1465                    const mods = ensureModifiers(input);
1466                    return cleanup(factory.updateModuleDeclaration(
1467                        input,
1468                        mods,
1469                        isExternalModuleAugmentation(input) ? rewriteModuleSpecifier(input, input.name) : input.name,
1470                        body
1471                    ));
1472                }
1473                else {
1474                    needsDeclare = previousNeedsDeclare;
1475                    const mods = ensureModifiers(input);
1476                    needsDeclare = false;
1477                    visitNode(inner, visitDeclarationStatements);
1478                    // eagerly transform nested namespaces (the nesting doesn't need any elision or painting done)
1479                    const id = getOriginalNodeId(inner!); // TODO: GH#18217
1480                    const body = lateStatementReplacementMap.get(id);
1481                    lateStatementReplacementMap.delete(id);
1482                    return cleanup(factory.updateModuleDeclaration(
1483                        input,
1484                        mods,
1485                        input.name,
1486                        body as ModuleBody
1487                    ));
1488                }
1489            }
1490            case SyntaxKind.StructDeclaration: {
1491                errorNameNode = input.name;
1492                errorFallbackNode = input;
1493
1494                const decorators = ensureEtsDecorators(input, host);
1495                const modifiers = factory.createNodeArray(ensureModifiers(input));
1496                const typeParameters = ensureTypeParams(input, input.typeParameters);
1497                const memberNodes = visitNodes(input.members, visitDeclarationSubtree, undefined, 1);
1498                const members = factory.createNodeArray(memberNodes);
1499
1500                return cleanup(factory.updateStructDeclaration(
1501                    input,
1502                    concatenateDecoratorsAndModifiers(decorators, modifiers),
1503                    input.name,
1504                    typeParameters,
1505                    /*heritageClauses*/ undefined,
1506                    members
1507                ));
1508            }
1509            case SyntaxKind.AnnotationDeclaration: {
1510                errorNameNode = input.name;
1511                errorFallbackNode = input;
1512
1513                const modifiers = factory.createNodeArray(ensureModifiers(input));
1514                const memberNodes = visitNodes(input.members, visitDeclarationSubtree);
1515                const members = factory.createNodeArray(memberNodes);
1516
1517                return cleanup(factory.updateAnnotationDeclaration(
1518                    input,
1519                    modifiers,
1520                    input.name,
1521                    members
1522                ));
1523            }
1524            case SyntaxKind.ClassDeclaration: {
1525                errorNameNode = input.name;
1526                errorFallbackNode = input;
1527                const modifiers = factory.createNodeArray(ensureModifiers(input));
1528                const typeParameters = ensureTypeParams(input, input.typeParameters);
1529                const ctor = getFirstConstructorWithBody(input);
1530                let parameterProperties: readonly PropertyDeclaration[] | undefined;
1531                if (ctor) {
1532                    const oldDiag = getSymbolAccessibilityDiagnostic;
1533                    parameterProperties = compact(flatMap(ctor.parameters, (param) => {
1534                        if (!hasSyntacticModifier(param, ModifierFlags.ParameterPropertyModifier) || shouldStripInternal(param)) return;
1535                        getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(param);
1536                        if (param.name.kind === SyntaxKind.Identifier) {
1537                            return preserveJsDoc(factory.createPropertyDeclaration(
1538                                ensureModifiers(param),
1539                                param.name,
1540                                param.questionToken,
1541                                ensureType(param, param.type),
1542                                ensureNoInitializer(param)), param);
1543                        }
1544                        else {
1545                            // Pattern - this is currently an error, but we emit declarations for it somewhat correctly
1546                            return walkBindingPattern(param.name);
1547                        }
1548
1549                        function walkBindingPattern(pattern: BindingPattern) {
1550                            let elems: PropertyDeclaration[] | undefined;
1551                            for (const elem of pattern.elements) {
1552                                if (isOmittedExpression(elem)) continue;
1553                                if (isBindingPattern(elem.name)) {
1554                                    elems = concatenate(elems, walkBindingPattern(elem.name));
1555                                }
1556                                elems = elems || [];
1557                                elems.push(factory.createPropertyDeclaration(
1558                                    ensureModifiers(param),
1559                                    elem.name as Identifier,
1560                                    /*questionToken*/ undefined,
1561                                    ensureType(elem, /*type*/ undefined),
1562                                    /*initializer*/ undefined
1563                                ));
1564                            }
1565                            return elems;
1566                        }
1567                    }));
1568                    getSymbolAccessibilityDiagnostic = oldDiag;
1569                }
1570
1571                const hasPrivateIdentifier = some(input.members, member => !!member.name && isPrivateIdentifier(member.name));
1572                // When the class has at least one private identifier, create a unique constant identifier to retain the nominal typing behavior
1573                // Prevents other classes with the same public members from being used in place of the current class
1574                const privateIdentifier = hasPrivateIdentifier ? [
1575                    factory.createPropertyDeclaration(
1576                        /*modifiers*/ undefined,
1577                        factory.createPrivateIdentifier("#private"),
1578                        /*questionToken*/ undefined,
1579                        /*type*/ undefined,
1580                        /*initializer*/ undefined
1581                    )
1582                ] : undefined;
1583                const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree));
1584                const members = factory.createNodeArray(memberNodes);
1585
1586                const extendsClause = getEffectiveBaseTypeNode(input);
1587                if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) {
1588                    // We must add a temporary declaration for the extends clause expression
1589
1590                    const oldId = input.name ? unescapeLeadingUnderscores(input.name.escapedText) : "default";
1591                    const newId = factory.createUniqueName(`${oldId}_base`, GeneratedIdentifierFlags.Optimistic);
1592                    getSymbolAccessibilityDiagnostic = () => ({
1593                        diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
1594                        errorNode: extendsClause,
1595                        typeName: input.name
1596                    });
1597                    const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(extendsClause.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
1598                    const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const));
1599                    const heritageClauses = factory.createNodeArray(map(input.heritageClauses, clause => {
1600                        if (clause.token === SyntaxKind.ExtendsKeyword) {
1601                            const oldDiag = getSymbolAccessibilityDiagnostic;
1602                            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]);
1603                            const newClause = factory.updateHeritageClause(clause, map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, visitNodes(t.typeArguments, visitDeclarationSubtree))));
1604                            getSymbolAccessibilityDiagnostic = oldDiag;
1605                            return newClause;
1606                        }
1607                        return factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree));
1608                    }));
1609                    let reservedDecorators = concatenate(getReservedDecoratorsOfEtsFile(input, host), getAnnotations(input));
1610                    checkAnnotationVisibilityByDecorator(reservedDecorators);
1611
1612                    return [statement, cleanup(factory.updateClassDeclaration(
1613                        input,
1614                        concatenateDecoratorsAndModifiers(reservedDecorators, modifiers),
1615                        input.name,
1616                        typeParameters,
1617                        heritageClauses,
1618                        members
1619                    ))!]; // TODO: GH#18217
1620                }
1621                else {
1622                    const heritageClauses = transformHeritageClauses(input.heritageClauses);
1623                    let reservedDecorators = concatenate(getReservedDecoratorsOfEtsFile(input, host), getAnnotations(input));
1624                    checkAnnotationVisibilityByDecorator(reservedDecorators);
1625                    return cleanup(factory.updateClassDeclaration(
1626                        input,
1627                        concatenateDecoratorsAndModifiers(reservedDecorators, modifiers),
1628                        input.name,
1629                        typeParameters,
1630                        heritageClauses,
1631                        members
1632                    ));
1633                }
1634            }
1635            case SyntaxKind.VariableStatement: {
1636                return cleanup(transformVariableStatement(input));
1637            }
1638            case SyntaxKind.EnumDeclaration: {
1639                return cleanup(factory.updateEnumDeclaration(input, factory.createNodeArray(ensureModifiers(input)), input.name, factory.createNodeArray(mapDefined(input.members, m => {
1640                    if (shouldStripInternal(m)) return;
1641                    // Rewrite enum values to their constants, if available
1642                    const constValue = resolver.getConstantValue(m);
1643                    return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m);
1644                }))));
1645            }
1646        }
1647
1648        function cleanup<T extends Node>(node: T | undefined): T | undefined {
1649            if (isEnclosingDeclaration(input)) {
1650                enclosingDeclaration = previousEnclosingDeclaration;
1651            }
1652            if (canProdiceDiagnostic) {
1653                getSymbolAccessibilityDiagnostic = oldDiag;
1654            }
1655            if (input.kind === SyntaxKind.ModuleDeclaration) {
1656                needsDeclare = previousNeedsDeclare;
1657            }
1658            if (node as Node === input) {
1659                return node;
1660            }
1661            errorFallbackNode = undefined;
1662            errorNameNode = undefined;
1663            return node && setOriginalNode(preserveJsDoc(node, input), input);
1664        }
1665    }
1666
1667    function transformVariableStatement(input: VariableStatement) {
1668        if (!forEach(input.declarationList.declarations, getBindingNameVisible)) return;
1669        const nodes = visitNodes(input.declarationList.declarations, visitDeclarationSubtree);
1670        if (!length(nodes)) return;
1671        return factory.updateVariableStatement(input, factory.createNodeArray(ensureModifiers(input)), factory.updateVariableDeclarationList(input.declarationList, nodes));
1672    }
1673
1674    function recreateBindingPattern(d: BindingPattern): VariableDeclaration[] {
1675        return flatten<VariableDeclaration>(mapDefined(d.elements, e => recreateBindingElement(e)));
1676    }
1677
1678    function recreateBindingElement(e: ArrayBindingElement) {
1679        if (e.kind === SyntaxKind.OmittedExpression) {
1680            return;
1681        }
1682        if (e.name) {
1683            if (!getBindingNameVisible(e)) return;
1684            if (isBindingPattern(e.name)) {
1685                return recreateBindingPattern(e.name);
1686            }
1687            else {
1688                return factory.createVariableDeclaration(e.name, /*exclamationToken*/ undefined, ensureType(e, /*type*/ undefined), /*initializer*/ undefined);
1689            }
1690        }
1691    }
1692
1693    function checkName(node: DeclarationDiagnosticProducing) {
1694        let oldDiag: typeof getSymbolAccessibilityDiagnostic | undefined;
1695        if (!suppressNewDiagnosticContexts) {
1696            oldDiag = getSymbolAccessibilityDiagnostic;
1697            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNodeName(node);
1698        }
1699        errorNameNode = (node as NamedDeclaration).name;
1700        Debug.assert(resolver.isLateBound(getParseTreeNode(node) as Declaration)); // Should only be called with dynamic names
1701        const decl = node as NamedDeclaration as LateBoundDeclaration;
1702        const entityName = decl.name.expression;
1703        checkEntityNameVisibility(entityName, enclosingDeclaration);
1704        if (!suppressNewDiagnosticContexts) {
1705            getSymbolAccessibilityDiagnostic = oldDiag!;
1706        }
1707        errorNameNode = undefined;
1708    }
1709
1710    function shouldStripInternal(node: Node) {
1711        return !!stripInternal && !!node && isInternalDeclaration(node, currentSourceFile);
1712    }
1713
1714    function isScopeMarker(node: Node) {
1715        return isExportAssignment(node) || isExportDeclaration(node);
1716    }
1717
1718    function hasScopeMarker(statements: readonly Statement[]) {
1719        return some(statements, isScopeMarker);
1720    }
1721
1722    function ensureModifiers<T extends HasModifiers>(node: T): readonly Modifier[] | undefined {
1723        const currentFlags = getEffectiveModifierFlags(node);
1724        const newFlags = ensureModifierFlags(node);
1725        if (currentFlags === newFlags) {
1726            return visitArray(node.modifiers, n => tryCast(n, isModifier), isModifier);
1727        }
1728        return factory.createModifiersFromModifierFlags(newFlags);
1729    }
1730
1731    function ensureModifierFlags(node: Node): ModifierFlags {
1732        let mask = ModifierFlags.All ^ (ModifierFlags.Public | ModifierFlags.Async | ModifierFlags.Override); // No async and override modifiers in declaration files
1733        let additions = (needsDeclare && !isAlwaysType(node)) ? ModifierFlags.Ambient : ModifierFlags.None;
1734        const parentIsFile = node.parent.kind === SyntaxKind.SourceFile;
1735        if (!parentIsFile || (isBundledEmit && parentIsFile && isExternalModule(node.parent as SourceFile))) {
1736            mask ^= ModifierFlags.Ambient;
1737            additions = ModifierFlags.None;
1738        }
1739        return maskModifierFlags(node, mask, additions);
1740    }
1741
1742    function getTypeAnnotationFromAllAccessorDeclarations(node: AccessorDeclaration, accessors: AllAccessorDeclarations) {
1743        let accessorType = getTypeAnnotationFromAccessor(node);
1744        if (!accessorType && node !== accessors.firstAccessor) {
1745            accessorType = getTypeAnnotationFromAccessor(accessors.firstAccessor);
1746            // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message
1747            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(accessors.firstAccessor);
1748        }
1749        if (!accessorType && accessors.secondAccessor && node !== accessors.secondAccessor) {
1750            accessorType = getTypeAnnotationFromAccessor(accessors.secondAccessor);
1751            // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message
1752            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(accessors.secondAccessor);
1753        }
1754        return accessorType;
1755    }
1756
1757    function transformHeritageClauses(nodes: NodeArray<HeritageClause> | undefined) {
1758        return factory.createNodeArray(filter(map(nodes, clause => factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => {
1759            return isEntityNameExpression(t.expression) || (clause.token === SyntaxKind.ExtendsKeyword && t.expression.kind === SyntaxKind.NullKeyword);
1760        })), visitDeclarationSubtree))), clause => clause.types && !!clause.types.length));
1761    }
1762}
1763
1764function isAlwaysType(node: Node) {
1765    if (node.kind === SyntaxKind.InterfaceDeclaration) {
1766        return true;
1767    }
1768    return false;
1769}
1770
1771// Elide "public" modifier, as it is the default
1772function maskModifiers(node: Node, modifierMask?: ModifierFlags, modifierAdditions?: ModifierFlags): Modifier[] | undefined {
1773    return factory.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions));
1774}
1775
1776function maskModifierFlags(node: Node, modifierMask: ModifierFlags = ModifierFlags.All ^ ModifierFlags.Public, modifierAdditions: ModifierFlags = ModifierFlags.None): ModifierFlags {
1777    let flags = (getEffectiveModifierFlags(node) & modifierMask) | modifierAdditions;
1778    if (flags & ModifierFlags.Default && !(flags & ModifierFlags.Export)) {
1779        // A non-exported default is a nonsequitor - we usually try to remove all export modifiers
1780        // from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid
1781        flags ^= ModifierFlags.Export;
1782    }
1783    if (flags & ModifierFlags.Default && flags & ModifierFlags.Ambient) {
1784        flags ^= ModifierFlags.Ambient; // `declare` is never required alongside `default` (and would be an error if printed)
1785    }
1786    return flags;
1787}
1788
1789function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode | undefined {
1790    if (accessor) {
1791        return accessor.kind === SyntaxKind.GetAccessor
1792            ? accessor.type // Getter - return type
1793            : accessor.parameters.length > 0
1794                ? accessor.parameters[0].type // Setter parameter type
1795                : undefined;
1796    }
1797}
1798
1799type CanHaveLiteralInitializer = VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration;
1800function canHaveLiteralInitializer(node: Node): boolean {
1801    switch (node.kind) {
1802        case SyntaxKind.PropertyDeclaration:
1803        case SyntaxKind.PropertySignature:
1804            return !hasEffectiveModifier(node, ModifierFlags.Private);
1805        case SyntaxKind.Parameter:
1806        case SyntaxKind.VariableDeclaration:
1807            return true;
1808    }
1809    return false;
1810}
1811
1812type ProcessedDeclarationStatement =
1813    | FunctionDeclaration
1814    | ModuleDeclaration
1815    | ImportEqualsDeclaration
1816    | InterfaceDeclaration
1817    | ClassDeclaration
1818    | TypeAliasDeclaration
1819    | EnumDeclaration
1820    | VariableStatement
1821    | ImportDeclaration
1822    | ExportDeclaration
1823    | ExportAssignment;
1824
1825function isPreservedDeclarationStatement(node: Node): node is ProcessedDeclarationStatement {
1826    switch (node.kind) {
1827        case SyntaxKind.FunctionDeclaration:
1828        case SyntaxKind.ModuleDeclaration:
1829        case SyntaxKind.ImportEqualsDeclaration:
1830        case SyntaxKind.InterfaceDeclaration:
1831        case SyntaxKind.ClassDeclaration:
1832        case SyntaxKind.StructDeclaration:
1833        case SyntaxKind.AnnotationDeclaration:
1834        case SyntaxKind.TypeAliasDeclaration:
1835        case SyntaxKind.EnumDeclaration:
1836        case SyntaxKind.VariableStatement:
1837        case SyntaxKind.ImportDeclaration:
1838        case SyntaxKind.ExportDeclaration:
1839        case SyntaxKind.ExportAssignment:
1840            return true;
1841    }
1842    return false;
1843}
1844
1845type ProcessedComponent =
1846    | ConstructSignatureDeclaration
1847    | ConstructorDeclaration
1848    | MethodDeclaration
1849    | GetAccessorDeclaration
1850    | SetAccessorDeclaration
1851    | PropertyDeclaration
1852    | AnnotationPropertyDeclaration
1853    | PropertySignature
1854    | MethodSignature
1855    | CallSignatureDeclaration
1856    | IndexSignatureDeclaration
1857    | VariableDeclaration
1858    | TypeParameterDeclaration
1859    | ExpressionWithTypeArguments
1860    | TypeReferenceNode
1861    | ConditionalTypeNode
1862    | FunctionTypeNode
1863    | ConstructorTypeNode
1864    | ImportTypeNode;
1865
1866function isProcessedComponent(node: Node): node is ProcessedComponent {
1867    switch (node.kind) {
1868        case SyntaxKind.ConstructSignature:
1869        case SyntaxKind.Constructor:
1870        case SyntaxKind.MethodDeclaration:
1871        case SyntaxKind.GetAccessor:
1872        case SyntaxKind.SetAccessor:
1873        case SyntaxKind.PropertyDeclaration:
1874        case SyntaxKind.AnnotationPropertyDeclaration:
1875        case SyntaxKind.PropertySignature:
1876        case SyntaxKind.MethodSignature:
1877        case SyntaxKind.CallSignature:
1878        case SyntaxKind.IndexSignature:
1879        case SyntaxKind.VariableDeclaration:
1880        case SyntaxKind.TypeParameter:
1881        case SyntaxKind.ExpressionWithTypeArguments:
1882        case SyntaxKind.TypeReference:
1883        case SyntaxKind.ConditionalType:
1884        case SyntaxKind.FunctionType:
1885        case SyntaxKind.ConstructorType:
1886        case SyntaxKind.ImportType:
1887            return true;
1888    }
1889    return false;
1890}
1891