@@ -2388,11 +2388,198 @@ namespace ts {
2388
2388
}
2389
2389
}
2390
2390
2391
+ function createTypeNode(type: Type) {
2392
+ let encounteredError = false;
2393
+ let checkAlias = true;
2394
+
2395
+ return createTypeNodeWorker(type);
2396
+
2397
+ function createTypeNodeWorker(type: Type): TypeNode {
2398
+ if(!type) {
2399
+ return undefined;
2400
+ }
2401
+
2402
+ if (checkAlias && type.aliasSymbol) {
2403
+ const name = getNameOfSymbol(type.aliasSymbol);
2404
+ const typeArguments = mapToTypeNodeArray(type.aliasTypeArguments);
2405
+ return createTypeReferenceNode(createIdentifier(name), typeArguments);
2406
+ }
2407
+ checkAlias = false;
2408
+
2409
+
2410
+ if(type.flags & TypeFlags.Any) {
2411
+ // TODO: add other case where type ends up being `any`.
2412
+ return createKeywordTypeNode(SyntaxKind.StringKeyword);
2413
+ }
2414
+ if(type.flags & TypeFlags.String) {
2415
+ return createKeywordTypeNode(SyntaxKind.StringKeyword);
2416
+ }
2417
+ if(type.flags & TypeFlags.Number) {
2418
+ return createKeywordTypeNode(SyntaxKind.NumberKeyword);
2419
+ }
2420
+ if(type.flags & (TypeFlags.Boolean | TypeFlags.StringOrNumberLiteral)) {
2421
+ // TODO: check if this actually works with boolean.
2422
+ return createLiteralTypeNode((<LiteralType>type).text);
2423
+ }
2424
+ if(type.flags & TypeFlags.Void) {
2425
+ return createKeywordTypeNode(SyntaxKind.VoidKeyword);
2426
+ }
2427
+ if(type.flags & TypeFlags.Undefined) {
2428
+ return createKeywordTypeNode(SyntaxKind.UndefinedKeyword);
2429
+ }
2430
+ if(type.flags & TypeFlags.Null) {
2431
+ return createKeywordTypeNode(SyntaxKind.NullKeyword);
2432
+ }
2433
+ if(type.flags & TypeFlags.Never) {
2434
+ return createKeywordTypeNode(SyntaxKind.NeverKeyword);
2435
+ }
2436
+ if(type.flags & TypeFlags.Enum) {
2437
+ throw new Error("not implemented");
2438
+ }
2439
+ if(type.flags & TypeFlags.ESSymbol) {
2440
+ throw new Error("not implemented");
2441
+ }
2442
+ if(type.flags & TypeFlags.TypeParameter) {
2443
+ const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(<TypeParameter>type));
2444
+ const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(<TypeParameter>type));
2445
+ if(!type.symbol) {
2446
+ encounteredError = true;
2447
+ throw new Error("No symbol for type parameter so can't get name");
2448
+ }
2449
+ const name = getNameOfSymbol(type.symbol);
2450
+ return createTypeParameterNode(name, constraint, defaultParameter);
2451
+ }
2452
+ if(type.flags & TypeFlags.Union) {
2453
+ throw new Error("not implemented");
2454
+ }
2455
+ if(type.flags & TypeFlags.Intersection) {
2456
+ throw new Error("not implemented");
2457
+ }
2458
+ if(type.flags & TypeFlags.Index) {
2459
+ throw new Error("not implemented");
2460
+ }
2461
+ if(type.flags & TypeFlags.IndexedAccess) {
2462
+ throw new Error("not implemented");
2463
+ }
2464
+
2465
+ // if(type.flags & TypeFlags.Object) {
2466
+ // throw new Error("not implemented");
2467
+ // }
2468
+
2469
+ // TODO: should these be within the if above (check with asserts)
2470
+ const objectFlags = getObjectFlags(type);
2471
+
2472
+ if (objectFlags & ObjectFlags.ClassOrInterface) {
2473
+ Debug.assert(!!(type.flags & TypeFlags.Object));
2474
+ // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above,
2475
+ // type must be an anonymous class or interface.
2476
+ return false;
2477
+ }
2478
+
2479
+ if (objectFlags & ObjectFlags.Reference) {
2480
+ Debug.assert(!!(type.flags & TypeFlags.Object));
2481
+ // and vice versa.
2482
+ // this case includes tuple types
2483
+ const typeArguments = (type as TypeReference).typeArguments || emptyArray;
2484
+ return allTypesVisible(typeArguments);
2485
+ }
2486
+
2487
+ // keyword types
2488
+ // this type node
2489
+ // function type node
2490
+ // constructor type node
2491
+ // type reference node
2492
+ // type predicate node - is Foo (for return types)
2493
+ // type query node -- typeof number
2494
+ // type literal node (like object literal)
2495
+ // array type
2496
+ // tuple type
2497
+ // union type
2498
+ // might need parens
2499
+ // intersection type
2500
+ // Type operator node (eg (ie?): keyof T)
2501
+ // IndexedAccess Type Node
2502
+ // mapped type node
2503
+ // literal type node
2504
+
2505
+ // if (inTypeAlias && type.aliasSymbol) {
2506
+ // return isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/false).accessibility === SymbolAccessibility.Accessible
2507
+ // && (!type.aliasTypeArguments || allTypesVisible(type.aliasTypeArguments));
2508
+ // }
2509
+ // const typeSymbolAccessibility = type.symbol && isSymbolAccessible(type.symbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility;
2510
+ // if (type.flags & TypeFlags.TypeParameter) {
2511
+ // if (inObjectLiteral && (type as TypeParameter).isThisType) {
2512
+ // return false;
2513
+ // }
2514
+ // const constraint = getConstraintFromTypeParameter((<TypeParameter>type));
2515
+ // return typeSymbolAccessibility === SymbolAccessibility.Accessible
2516
+ // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false));
2517
+ // }
2518
+ // if (typeSymbolAccessibility === SymbolAccessibility.Accessible) {
2519
+ // return true;
2520
+ // }
2521
+ // if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) {
2522
+ // return true;
2523
+ // }
2524
+ // const objectFlags = getObjectFlags(type);
2525
+ // if (objectFlags & ObjectFlags.ClassOrInterface) {
2526
+ // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above,
2527
+ // // type must be an anonymous class or interface.
2528
+ // return false;
2529
+ // }
2530
+ // if (objectFlags & ObjectFlags.Reference) {
2531
+ // // and vice versa.
2532
+ // // this case includes tuple types
2533
+ // const typeArguments = (type as TypeReference).typeArguments || emptyArray;
2534
+ // return allTypesVisible(typeArguments);
2535
+ // }
2536
+ // if (type.flags & TypeFlags.UnionOrIntersection) {
2537
+ // return allTypesVisible((type as UnionOrIntersectionType).types);
2538
+ // }
2539
+
2540
+ if (objectFlags & ObjectFlags.Mapped) {
2541
+ Debug.assert(!!(type.flags & TypeFlags.Object));
2542
+ const typeParameter = getTypeParameterFromMappedType(<MappedType>type);
2543
+ const constraintType = getConstraintTypeFromMappedType(<MappedType>type);
2544
+ const templateType = getTemplateTypeFromMappedType(<MappedType>type);
2545
+ }
2546
+
2547
+ if (objectFlags & ObjectFlags.Anonymous) {
2548
+ Debug.assert(!!(type.flags & TypeFlags.Object));
2549
+ // The type is an object literal type.
2550
+ if (!type.symbol) {
2551
+ // Anonymous types without symbols are literals.
2552
+ return true;
2553
+ }
2554
+ // what case is this?
2555
+ const members = type.symbol.members;
2556
+ let allVisible = true;
2557
+ members && members.forEach((member) => {
2558
+ const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration);
2559
+ allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false);
2560
+ });
2561
+ return allVisible;
2562
+ }
2563
+
2564
+ Debug.fail("Should be unreachable here");
2565
+
2566
+ /** Note that mapToTypeNodeArray(undefined) === undefined. */
2567
+ function mapToTypeNodeArray(types: Type[]): NodeArray<TypeNode> {
2568
+ return asNodeArray(types && types.map(createTypeNodeWorker));
2569
+ }
2570
+ // function allTypesVisible(types: Type[]): boolean {
2571
+ // return types.every(type => isTypeAccessibleWorker(type, inObjectLiteral, /*inTypeAlias*/false));
2572
+ // }
2573
+ }
2574
+ }
2575
+
2391
2576
function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) {
2392
2577
const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike;
2393
2578
let inObjectTypeLiteral = false;
2394
2579
return writeType(type, globalFlags);
2395
2580
2581
+ const typeNode = createTypeNode(type, enclosingDeclaration);
2582
+
2396
2583
function writeType(type: Type, flags: TypeFormatFlags) {
2397
2584
const nextFlags = flags & ~TypeFormatFlags.InTypeAlias;
2398
2585
// Write undefined/null type as any
@@ -6939,6 +7126,10 @@ namespace ts {
6939
7126
}
6940
7127
}
6941
7128
7129
+ // export function synthesizeTypeNode(type: Type, enclosingDeclaration: Node): TypeNode {
7130
+ // throw new Error("Not implemented" + enclosingDeclaration);
7131
+ // }
7132
+
6942
7133
function instantiateList<T>(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] {
6943
7134
if (items && items.length) {
6944
7135
const result: T[] = [];
0 commit comments