Skip to content

Commit f0b4efe

Browse files
author
Arthur Ozga
committed
type literals, properties only
1 parent 6fe59f3 commit f0b4efe

9 files changed

Lines changed: 97 additions & 73 deletions

src/compiler/checker.ts

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,25 +2196,6 @@ namespace ts {
21962196

21972197
return createTypeNodeWorker(type);
21982198

2199-
// function createTypeDeclaration(type: Type): Declaration {
2200-
// if (!type) {
2201-
// if (undefinedArgumentIsError) { encounteredError = true; }
2202-
// return undefined;
2203-
// }
2204-
// if (type.flags & TypeFlags.TypeParameter) {
2205-
// const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(<TypeParameter>type)) as TypeNode;
2206-
// const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(<TypeParameter>type)) as TypeNode;
2207-
// if (!type.symbol) {
2208-
// encounteredError = true;
2209-
// throw new Error("No symbol for type parameter so can't get name");
2210-
// }
2211-
// const name = getNameOfSymbol(type.symbol);
2212-
// return createTypeParameterDeclaration(name, constraint, defaultParameter);
2213-
// }
2214-
2215-
// throw new Error("type declarations not implemented.");
2216-
// }
2217-
22182199
function createTypeNodeWorker(type: Type): TypeNode {
22192200
if (!type) {
22202201
if (undefinedArgumentIsError) { encounteredError = true; }
@@ -2267,6 +2248,9 @@ namespace ts {
22672248
throw new Error("ESSymbol not implemented");
22682249
}
22692250
if (type.flags & TypeFlags.TypeParameter) {
2251+
if ((<TypeParameter>type).isThisType) {
2252+
return createThis();
2253+
}
22702254
throw new Error("Type Parameter declarations only handled in other worker.");
22712255
}
22722256
if (type.flags & TypeFlags.Union) {
@@ -2332,27 +2316,12 @@ namespace ts {
23322316
// return typeSymbolAccessibility === SymbolAccessibility.Accessible
23332317
// && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false));
23342318
// }
2335-
// if (typeSymbolAccessibility === SymbolAccessibility.Accessible) {
2336-
// return true;
2337-
// }
2338-
// if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) {
2339-
// return true;
2340-
// }
23412319
// const objectFlags = getObjectFlags(type);
23422320
// if (objectFlags & ObjectFlags.ClassOrInterface) {
23432321
// // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above,
23442322
// // type must be an anonymous class or interface.
23452323
// return false;
23462324
// }
2347-
// if (objectFlags & ObjectFlags.Reference) {
2348-
// // and vice versa.
2349-
// // this case includes tuple types
2350-
// const typeArguments = (type as TypeReference).typeArguments || emptyArray;
2351-
// return allTypesVisible(typeArguments);
2352-
// }
2353-
// if (type.flags & TypeFlags.UnionOrIntersection) {
2354-
// return allTypesVisible((type as UnionOrIntersectionType).types);
2355-
// }
23562325

23572326
if (objectFlags & ObjectFlags.Mapped) {
23582327
Debug.assert(!!(type.flags & TypeFlags.Object));
@@ -2370,25 +2339,68 @@ namespace ts {
23702339

23712340

23722341
// mapToTypeDeclarationsArray(type)
2373-
throw new Error("object literal types not implemented.");
2342+
throw new Error("unknown case.");
23742343
}
2375-
// what case is this?
2376-
throw new Error("unknown case.")
2377-
// const members = type.symbol.members;
2378-
// let allVisible = true;
2379-
// members && members.forEach((member) => {
2380-
// const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration);
2381-
// allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false);
2382-
// });
2383-
// return allVisible;
2344+
2345+
const members = type.symbol.members;
2346+
const newMembers: TypeElement[] = [];
2347+
memberLoop: for(const key in members){
2348+
const oldMember = members.get(key);
2349+
const name = getNameOfSymbol(oldMember);
2350+
const oldDeclaration = oldMember.declarations && oldMember.declarations[0] as TypeElement;
2351+
if(!oldDeclaration) {
2352+
continue memberLoop;
2353+
}
2354+
2355+
const kind = oldDeclaration.kind;
2356+
2357+
switch (kind) {
2358+
case SyntaxKind.PropertySignature:
2359+
const optional = !!oldDeclaration.questionToken;
2360+
newMembers.push(createPropertySignature(
2361+
createIdentifier(name)
2362+
, optional ? createToken(SyntaxKind.QuestionToken) : undefined
2363+
, createTypeNode(getTypeOfSymbol(oldMember))));
2364+
case SyntaxKind.MethodSignature:
2365+
case SyntaxKind.CallSignature:
2366+
case SyntaxKind.ConstructSignature:
2367+
case SyntaxKind.IndexSignature:
2368+
default:
2369+
throw new Error("type literal constituent not implemented.");
2370+
}
2371+
}
2372+
return createTypeLiteralNode(newMembers);
23842373
}
23852374

23862375
Debug.fail("Should be unreachable.");
23872376

2377+
// function createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration {
2378+
// if (!type) {
2379+
// if (undefinedArgumentIsError) { encounteredError = true; }
2380+
// return undefined;
2381+
// }
2382+
// if (type.flags & TypeFlags.TypeParameter) {
2383+
// const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(<TypeParameter>type)) as TypeNode;
2384+
// const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(<TypeParameter>type)) as TypeNode;
2385+
// if (!type.symbol) {
2386+
// encounteredError = true;
2387+
// throw new Error("No symbol for type parameter so can't get name");
2388+
// }
2389+
// const name = getNameOfSymbol(type.symbol);
2390+
// return createTypeParameterDeclaration(name, constraint, defaultParameter);
2391+
// }
2392+
// throw new Error("type declarations not implemented.");
2393+
// }
2394+
23882395
/** Note that mapToTypeNodeArray(undefined) === undefined. */
23892396
function mapToTypeNodeArray(types: Type[]): NodeArray<TypeNode> {
23902397
return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]);
23912398
}
2399+
2400+
// /** Note that mapToTypeNodeArray(undefined) === undefined. */
2401+
// function mapToTypeParameterArray(types: Type[]): NodeArray<TypeNode> {
2402+
// return asNodeArray(types && types.map(createTypeParameterDeclarationFromType) as TypeNode[]);
2403+
// }
23922404
}
23932405
}
23942406

src/compiler/factory.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ namespace ts {
6767
return clone;
6868
}
6969

70+
/* @internal */
71+
export function getSynthesizedDeepClone<T extends Node>(node: T | undefined): T {
72+
if (node === undefined) {
73+
return undefined;
74+
}
75+
return getSynthesizedClone(visitEachChild(node, getSynthesizedClone, nullTransformationContext));
76+
}
77+
7078
// Literals
7179

7280
export function createLiteral(value: string): StringLiteral;
@@ -173,11 +181,11 @@ namespace ts {
173181
}
174182

175183
export function createThis() {
176-
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.ThisKeyword);
184+
return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.ThisKeyword);
177185
}
178186

179187
export function createNull() {
180-
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.NullKeyword);
188+
return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.NullKeyword);
181189
}
182190

183191
export function createTrue() {

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4065,7 +4065,7 @@ namespace ts {
40654065
export type Transformer<T extends Node> = (node: T) => T;
40664066

40674067
/**
4068-
* A function that accepts and possible transforms a node.
4068+
* A function that accepts and possibly transforms a node.
40694069
*/
40704070
export type Visitor = (node: Node) => VisitResult<Node>;
40714071

src/compiler/visitor.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,28 @@
33
/// <reference path="utilities.ts" />
44

55
namespace ts {
6+
7+
8+
export const nullTransformationContext: TransformationContext = {
9+
enableEmitNotification: noop,
10+
enableSubstitution: noop,
11+
endLexicalEnvironment: () => undefined,
12+
getCompilerOptions: notImplemented,
13+
getEmitHost: notImplemented,
14+
getEmitResolver: notImplemented,
15+
hoistFunctionDeclaration: noop,
16+
hoistVariableDeclaration: noop,
17+
isEmitNotificationEnabled: notImplemented,
18+
isSubstitutionEnabled: notImplemented,
19+
onEmitNode: noop,
20+
onSubstituteNode: notImplemented,
21+
readEmitHelpers: notImplemented,
22+
requestEmitHelper: noop,
23+
resumeLexicalEnvironment: noop,
24+
startLexicalEnvironment: noop,
25+
suspendLexicalEnvironment: noop
26+
};
27+
628
/**
729
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
830
*
@@ -813,7 +835,8 @@ namespace ts {
813835
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
814836

815837
default:
816-
return node;
838+
throw new Error("not handled");
839+
// return node;
817840
}
818841
}
819842

src/services/codefixes/helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ namespace ts.codefix {
5151
}
5252

5353
const declaration = declarations[0] as Declaration;
54+
// TODO: get name as identifier or computer property name, etc.
5455
const name = declaration.name ? declaration.name.getText() : undefined;
5556
const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration));
5657
const modifiers = visibilityModifier ? [visibilityModifier] : undefined;

src/services/textChanges.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -341,26 +341,6 @@ namespace ts.textChanges {
341341
return skipTrivia(s, 0) === s.length;
342342
}
343343

344-
const nullTransformationContext: TransformationContext = {
345-
enableEmitNotification: noop,
346-
enableSubstitution: noop,
347-
endLexicalEnvironment: () => undefined,
348-
getCompilerOptions: notImplemented,
349-
getEmitHost: notImplemented,
350-
getEmitResolver: notImplemented,
351-
hoistFunctionDeclaration: noop,
352-
hoistVariableDeclaration: noop,
353-
isEmitNotificationEnabled: notImplemented,
354-
isSubstitutionEnabled: notImplemented,
355-
onEmitNode: noop,
356-
onSubstituteNode: notImplemented,
357-
readEmitHelpers: notImplemented,
358-
requestEmitHelper: noop,
359-
resumeLexicalEnvironment: noop,
360-
startLexicalEnvironment: noop,
361-
suspendLexicalEnvironment: noop
362-
};
363-
364344
function assignPositionsToNode(node: Node): Node {
365345
const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray);
366346
// create proxy node for non synthesized nodes

tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
//// abstract z: number;
77
//// }
88
////
9-
//// class C extends A {[| |]
10-
//// constructor(public x: number) { super(); }
9+
//// class C extends A {[|
10+
//// |]constructor(public x: number) { super(); }
1111
//// y: number;
1212
//// }
1313

tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
////
99
//// }
1010
////
11-
//// class C3 implements C2 {[| |]
12-
//// f2(){}
11+
//// class C3 implements C2 {[|
12+
//// |]f2(){}
1313
//// }
1414

1515
verify.rangeAfterCodeFix(`f1(): void{

tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//// [2]: boolean;
88
//// }
99
////
10-
//// class C implements I {[| |]}
10+
//// class C implements I {[| |]}
1111

1212
verify.rangeAfterCodeFix(`
1313
["foo"](o: any): boolean {

0 commit comments

Comments
 (0)