@@ -2448,9 +2448,10 @@ namespace ts {
2448
2448
2449
2449
if (!inTypeAlias && type.aliasSymbol &&
2450
2450
isSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
2451
- const name = symbolToName (type.aliasSymbol, /*expectsIdentifier*/ false, SymbolFlags.Type, context );
2452
- const typeArgumentNodes = type.aliasTypeArguments && mapToTypeNodeArray (type.aliasTypeArguments, context, /*addInElementTypeFlag*/ false, /*addInFirstTypeArgumentFlag*/ true );
2451
+ const name = symbolToTypeReferenceName (type.aliasSymbol);
2452
+ const typeArgumentNodes = toTypeArgumentNodes (type.aliasTypeArguments, context);
2453
2453
return createTypeReferenceNode(name, typeArgumentNodes);
2454
+ // return symbolToTypeReferenceIdentifier(type.aliasSymbol, type.aliasTypeArguments);
2454
2455
}
2455
2456
2456
2457
if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) {
@@ -2614,6 +2615,13 @@ namespace ts {
2614
2615
return createTypeQueryNode(entityName);
2615
2616
}
2616
2617
2618
+ function symbolToTypeReferenceName(symbol: Symbol) {
2619
+ // Unnamed function expressions and arrow functions have reserved names that we don't want to display
2620
+ const entityName = symbol.flags & SymbolFlags.Class || !isReservedMemberName(symbol.name) ? symbolToName(symbol, /*expectsIdentifier*/ false, SymbolFlags.Type, context) : createIdentifier("");
2621
+ // TODO: assert no type args?
2622
+ return entityName;
2623
+ }
2624
+
2617
2625
function typeReferenceToTypeNode(type: TypeReference) {
2618
2626
const typeArguments: Type[] = type.typeArguments || emptyArray;
2619
2627
if (type.target === globalArrayType) {
@@ -2641,7 +2649,7 @@ namespace ts {
2641
2649
else {
2642
2650
const outerTypeParameters = type.target.outerTypeParameters;
2643
2651
let i = 0;
2644
- let qualifiedName: QualifiedName | undefined = undefined ;
2652
+ let qualifiedName: QualifiedName | undefined;
2645
2653
if (outerTypeParameters) {
2646
2654
let inFirstTypeArgument = true;
2647
2655
const length = outerTypeParameters.length;
@@ -2655,46 +2663,68 @@ namespace ts {
2655
2663
// When type parameters are their own type arguments for the whole group (i.e. we have
2656
2664
// the default outer type arguments), we don't show the group.
2657
2665
if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) {
2658
- const qualifiedNamePartTypeArguments = typeArguments.slice(start,i);
2659
- const qualifiedNamePartTypeArgumentNodes = qualifiedNamePartTypeArguments && createNodeArray(mapToTypeNodeArray(qualifiedNamePartTypeArguments, context, /*addInElementTypeFlag*/ false, /*addInFirstTypeArgumentFlag*/ true));
2660
- const qualifiedNamePart = symbolToName(parent, /*expectsIdentifier*/ true, SymbolFlags.Type, context);
2661
- qualifiedNamePart.typeArguments = qualifiedNamePartTypeArgumentNodes;
2666
+ const typeArgumentNodes = createNodeArray(toTypeArgumentNodes(typeArguments.slice(start, i), context));
2667
+ const namePart = symbolToTypeReferenceName(parent);
2668
+ (namePart.kind === SyntaxKind.Identifier ? <Identifier>namePart : namePart.right).typeArguments = typeArgumentNodes;
2662
2669
2663
- if (!qualifiedName) {
2664
- qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined);
2665
- }
2666
- else {
2670
+ if (qualifiedName) {
2667
2671
Debug.assert(!qualifiedName.right);
2668
- qualifiedName.right = qualifiedNamePart ;
2672
+ qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, namePart) ;
2669
2673
qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined);
2670
2674
}
2675
+ else {
2676
+ qualifiedName = createQualifiedName(namePart, /*right*/ undefined);
2677
+ }
2671
2678
}
2672
2679
inFirstTypeArgument = false;
2673
2680
}
2674
2681
}
2682
+
2675
2683
let entityName: EntityName = undefined;
2676
- const nameIdentifier = symbolToName (type.symbol, /*expectsIdentifier*/ true, SymbolFlags.Type, context );
2684
+ const nameIdentifier = symbolToTypeReferenceName (type.symbol);
2677
2685
if (qualifiedName) {
2678
2686
Debug.assert(!qualifiedName.right);
2679
- qualifiedName.right = nameIdentifier;
2687
+ qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, nameIdentifier) ;
2680
2688
entityName = qualifiedName;
2681
2689
}
2682
2690
else {
2683
2691
entityName = nameIdentifier;
2684
2692
}
2685
- const typeParameterCount = (type.target.typeParameters || emptyArray).length;
2686
2693
2687
2694
let typeArgumentNodes: TypeNode[] | undefined;
2688
2695
if (some(typeArguments)) {
2689
- const slice = typeArguments.slice(i, typeParameterCount - i);
2690
- context.InFirstTypeArgument = true;
2691
- typeArgumentNodes = mapToTypeNodeArray(slice, context, /*addInElementTypeFlag*/ false, /*addInFirstTypeArgumentFlag*/ true);
2696
+ const typeParameterCount = (type.target.typeParameters || emptyArray).length;
2697
+ const slice = typeArguments && typeArguments.slice(i, typeParameterCount);
2698
+ typeArgumentNodes = toTypeArgumentNodes(slice, context);
2699
+ }
2700
+
2701
+ if (typeArgumentNodes) {
2702
+ const lastIdentifier = entityName.kind === SyntaxKind.Identifier ? <Identifier>entityName : entityName.right;
2703
+ lastIdentifier.typeArguments = undefined;
2692
2704
}
2693
2705
2694
2706
return createTypeReferenceNode(entityName, typeArgumentNodes);
2695
2707
}
2696
2708
}
2697
2709
2710
+ function addToQualifiedNameMissingRightIdentifier(left: QualifiedName, right: Identifier | QualifiedName) {
2711
+ Debug.assert(left.right === undefined);
2712
+
2713
+ if (right.kind === SyntaxKind.Identifier) {
2714
+ left.right = right;
2715
+ return left;
2716
+ }
2717
+
2718
+ let rightPart = right;
2719
+ while (rightPart.left.kind !== SyntaxKind.Identifier) {
2720
+ rightPart = rightPart.left;
2721
+ }
2722
+
2723
+ left.right = <Identifier>rightPart.left;
2724
+ rightPart.left = left;
2725
+ return right;
2726
+ }
2727
+
2698
2728
function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] {
2699
2729
const typeElements: TypeElement[] = [];
2700
2730
for (const signature of resolvedType.callSignatures) {
@@ -2754,7 +2784,7 @@ namespace ts {
2754
2784
const result = [];
2755
2785
Debug.assert(context.InElementType === false, "should be unset at the beginning of the helper");
2756
2786
for (let i = 0; i < types.length; ++i) {
2757
- let type = types[i]
2787
+ const type = types[i];
2758
2788
context.InElementType = addInElementTypeFlag;
2759
2789
if (i === 0) {
2760
2790
context.InFirstTypeArgument = addInFirstTypeArgumentFlag;
@@ -2768,6 +2798,10 @@ namespace ts {
2768
2798
return result;
2769
2799
}
2770
2800
2801
+ function toTypeArgumentNodes(typeArguments: Type[], context: NodeBuilderContext) {
2802
+ return typeArguments && mapToTypeNodeArray(typeArguments, context, /*addInElementTypeFlag*/ false, /*addInFirstTypeArgumentFlag*/ true);
2803
+ }
2804
+
2771
2805
function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, context: NodeBuilderContext): IndexSignatureDeclaration {
2772
2806
const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword);
2773
2807
const name = getNameFromIndexInfo(indexInfo) || "x";
@@ -2913,7 +2947,7 @@ namespace ts {
2913
2947
if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowTypeParameterInQualifiedName)) {
2914
2948
context.encounteredError = true;
2915
2949
}
2916
- typeParameterNodes = typeParameters && mapToTypeNodeArray (typeParameters, context, /*addInElementTypeFlag*/ false, /*addInFirstTypeArgumentFlag*/ true );
2950
+ typeParameterNodes = toTypeArgumentNodes (typeParameters, context);
2917
2951
}
2918
2952
}
2919
2953
0 commit comments