@@ -2953,7 +2953,7 @@ namespace ts {
2953
2953
if (type.flags & TypeFlags.UniqueESSymbol) {
2954
2954
if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) {
2955
2955
if (isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
2956
- return createTypeQueryNode(symbolToName( type.symbol, context, SymbolFlags.Value, /*expectsIdentifier*/ false) );
2956
+ return symbolToTypeNode( type.symbol, context, SymbolFlags.Value);
2957
2957
}
2958
2958
if (context.tracker.reportInaccessibleUniqueSymbolError) {
2959
2959
context.tracker.reportInaccessibleUniqueSymbolError();
@@ -3072,15 +3072,14 @@ namespace ts {
3072
3072
if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) ||
3073
3073
symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) ||
3074
3074
shouldWriteTypeOfFunctionSymbol()) {
3075
- return createTypeQueryNodeFromSymbol (symbol, SymbolFlags.Value);
3075
+ return symbolToTypeNode (symbol, context , SymbolFlags.Value);
3076
3076
}
3077
3077
else if (contains(context.symbolStack, symbol)) {
3078
3078
// If type is an anonymous type literal in a type alias declaration, use type alias name
3079
3079
const typeAlias = getTypeAliasForTypeLiteral(type);
3080
3080
if (typeAlias) {
3081
3081
// The specified symbol flags need to be reinterpreted as type flags
3082
- const entityName = symbolToName(typeAlias, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
3083
- return createTypeReferenceNode(entityName, /*typeArguments*/ undefined);
3082
+ return symbolToTypeNode(typeAlias, context, SymbolFlags.Type);
3084
3083
}
3085
3084
else {
3086
3085
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
@@ -3158,11 +3157,6 @@ namespace ts {
3158
3157
return setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine);
3159
3158
}
3160
3159
3161
- function createTypeQueryNodeFromSymbol(symbol: Symbol, symbolFlags: SymbolFlags) {
3162
- const entityName = symbolToName(symbol, context, symbolFlags, /*expectsIdentifier*/ false);
3163
- return createTypeQueryNode(entityName);
3164
- }
3165
-
3166
3160
function symbolToTypeReferenceName(symbol: Symbol) {
3167
3161
// Unnamed function expressions and arrow functions have reserved names that we don't want to display
3168
3162
const entityName = symbol.flags & SymbolFlags.Class || !isReservedMemberName(symbol.escapedName) ? symbolToName(symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false) : createIdentifier("");
@@ -3559,6 +3553,41 @@ namespace ts {
3559
3553
return typeParameterNodes;
3560
3554
}
3561
3555
3556
+ function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags): TypeQueryNode | TypeReferenceNode | ImportTypeNode {
3557
+ const chain = lookupSymbolChain(symbol, context, meaning);
3558
+
3559
+ context.flags |= NodeBuilderFlags.InInitialEntityName;
3560
+ const rootName = getNameOfSymbolAsWritten(chain[0], context);
3561
+ context.flags ^= NodeBuilderFlags.InInitialEntityName;
3562
+
3563
+ const isTypeOf = meaning === SymbolFlags.Value;
3564
+ if (ambientModuleSymbolRegex.test(rootName)) {
3565
+ // module is root, must use `ImportTypeNode`
3566
+ const nonRootParts = chain.length > 1 ? createEntityNameFromSymbolChain(chain, chain.length - 1, 1) : undefined;
3567
+ return createImportTypeNode(createLiteralTypeNode(createLiteral(rootName.substring(1, rootName.length - 1))), nonRootParts, isTypeOf);
3568
+ }
3569
+
3570
+ const entityName = createEntityNameFromSymbolChain(chain, chain.length - 1, 0);
3571
+ return isTypeOf ? createTypeQueryNode(entityName) : createTypeReferenceNode(entityName, /*typeArguments*/ undefined);
3572
+
3573
+ function createEntityNameFromSymbolChain(chain: Symbol[], index: number, stopper: number): EntityName {
3574
+ const typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
3575
+ const symbol = chain[index];
3576
+
3577
+ if (index === 0) {
3578
+ context.flags |= NodeBuilderFlags.InInitialEntityName;
3579
+ }
3580
+ const symbolName = getNameOfSymbolAsWritten(symbol, context);
3581
+ if (index === 0) {
3582
+ context.flags ^= NodeBuilderFlags.InInitialEntityName;
3583
+ }
3584
+ const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
3585
+ identifier.symbol = symbol;
3586
+
3587
+ return index > stopper ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1, stopper), identifier) : identifier;
3588
+ }
3589
+ }
3590
+
3562
3591
function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: true): Identifier;
3563
3592
function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: false): EntityName;
3564
3593
function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: boolean): EntityName {
0 commit comments