diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d3e1eeb08e..65907536f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2196,25 +2196,6 @@ namespace ts { return createTypeNodeWorker(type); - // function createTypeDeclaration(type: Type): Declaration { - // if (!type) { - // if (undefinedArgumentIsError) { encounteredError = true; } - // return undefined; - // } - // if (type.flags & TypeFlags.TypeParameter) { - // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; - // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; - // if (!type.symbol) { - // encounteredError = true; - // throw new Error("No symbol for type parameter so can't get name"); - // } - // const name = getNameOfSymbol(type.symbol); - // return createTypeParameterDeclaration(name, constraint, defaultParameter); - // } - - // throw new Error("type declarations not implemented."); - // } - function createTypeNodeWorker(type: Type): TypeNode { if (!type) { if (undefinedArgumentIsError) { encounteredError = true; } @@ -2267,6 +2248,9 @@ namespace ts { throw new Error("ESSymbol not implemented"); } if (type.flags & TypeFlags.TypeParameter) { + if ((type).isThisType) { + return createThis(); + } throw new Error("Type Parameter declarations only handled in other worker."); } if (type.flags & TypeFlags.Union) { @@ -2332,27 +2316,12 @@ namespace ts { // return typeSymbolAccessibility === SymbolAccessibility.Accessible // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); // } - // if (typeSymbolAccessibility === SymbolAccessibility.Accessible) { - // return true; - // } - // if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) { - // return true; - // } // const objectFlags = getObjectFlags(type); // if (objectFlags & ObjectFlags.ClassOrInterface) { // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, // // type must be an anonymous class or interface. // return false; // } - // if (objectFlags & ObjectFlags.Reference) { - // // and vice versa. - // // this case includes tuple types - // const typeArguments = (type as TypeReference).typeArguments || emptyArray; - // return allTypesVisible(typeArguments); - // } - // if (type.flags & TypeFlags.UnionOrIntersection) { - // return allTypesVisible((type as UnionOrIntersectionType).types); - // } if (objectFlags & ObjectFlags.Mapped) { Debug.assert(!!(type.flags & TypeFlags.Object)); @@ -2370,25 +2339,68 @@ namespace ts { // mapToTypeDeclarationsArray(type) - throw new Error("object literal types not implemented."); + throw new Error("unknown case."); } - // what case is this? - throw new Error("unknown case.") - // const members = type.symbol.members; - // let allVisible = true; - // members && members.forEach((member) => { - // const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration); - // allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false); - // }); - // return allVisible; + + const members = type.symbol.members; + const newMembers: TypeElement[] = []; + memberLoop: for(const key in members){ + const oldMember = members.get(key); + const name = getNameOfSymbol(oldMember); + const oldDeclaration = oldMember.declarations && oldMember.declarations[0] as TypeElement; + if(!oldDeclaration) { + continue memberLoop; + } + + const kind = oldDeclaration.kind; + + switch (kind) { + case SyntaxKind.PropertySignature: + const optional = !!oldDeclaration.questionToken; + newMembers.push(createPropertySignature( + createIdentifier(name) + , optional ? createToken(SyntaxKind.QuestionToken) : undefined + , createTypeNode(getTypeOfSymbol(oldMember)))); + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: + default: + throw new Error("type literal constituent not implemented."); + } + } + return createTypeLiteralNode(newMembers); } Debug.fail("Should be unreachable."); + // function createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration { + // if (!type) { + // if (undefinedArgumentIsError) { encounteredError = true; } + // return undefined; + // } + // if (type.flags & TypeFlags.TypeParameter) { + // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; + // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; + // if (!type.symbol) { + // encounteredError = true; + // throw new Error("No symbol for type parameter so can't get name"); + // } + // const name = getNameOfSymbol(type.symbol); + // return createTypeParameterDeclaration(name, constraint, defaultParameter); + // } + // throw new Error("type declarations not implemented."); + // } + /** Note that mapToTypeNodeArray(undefined) === undefined. */ function mapToTypeNodeArray(types: Type[]): NodeArray { return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); } + + // /** Note that mapToTypeNodeArray(undefined) === undefined. */ + // function mapToTypeParameterArray(types: Type[]): NodeArray { + // return asNodeArray(types && types.map(createTypeParameterDeclarationFromType) as TypeNode[]); + // } } } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 6e10d8bb22..88bf5f458f 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -67,6 +67,14 @@ namespace ts { return clone; } + /* @internal */ + export function getSynthesizedDeepClone(node: T | undefined): T { + if (node === undefined) { + return undefined; + } + return getSynthesizedClone(visitEachChild(node, getSynthesizedClone, nullTransformationContext)); + } + // Literals export function createLiteral(value: string): StringLiteral; @@ -173,11 +181,11 @@ namespace ts { } export function createThis() { - return createSynthesizedNode(SyntaxKind.ThisKeyword); + return createSynthesizedNode(SyntaxKind.ThisKeyword); } export function createNull() { - return createSynthesizedNode(SyntaxKind.NullKeyword); + return createSynthesizedNode(SyntaxKind.NullKeyword); } export function createTrue() { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b9f5da0f6e..bf8916026f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4065,7 +4065,7 @@ namespace ts { export type Transformer = (node: T) => T; /** - * A function that accepts and possible transforms a node. + * A function that accepts and possibly transforms a node. */ export type Visitor = (node: Node) => VisitResult; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index bd2d26b775..d2991b7cf0 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -3,6 +3,28 @@ /// namespace ts { + + + export const nullTransformationContext: TransformationContext = { + enableEmitNotification: noop, + enableSubstitution: noop, + endLexicalEnvironment: () => undefined, + getCompilerOptions: notImplemented, + getEmitHost: notImplemented, + getEmitResolver: notImplemented, + hoistFunctionDeclaration: noop, + hoistVariableDeclaration: noop, + isEmitNotificationEnabled: notImplemented, + isSubstitutionEnabled: notImplemented, + onEmitNode: noop, + onSubstituteNode: notImplemented, + readEmitHelpers: notImplemented, + requestEmitHelper: noop, + resumeLexicalEnvironment: noop, + startLexicalEnvironment: noop, + suspendLexicalEnvironment: noop + }; + /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -813,7 +835,8 @@ namespace ts { visitNode((node).expression, visitor, isExpression)); default: - return node; + throw new Error("not handled"); + // return node; } } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 67f53fb8e5..fb76e83faa 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -51,6 +51,7 @@ namespace ts.codefix { } const declaration = declarations[0] as Declaration; + // TODO: get name as identifier or computer property name, etc. const name = declaration.name ? declaration.name.getText() : undefined; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? [visibilityModifier] : undefined; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 5c345e6e4e..cb8c614cb2 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -341,26 +341,6 @@ namespace ts.textChanges { return skipTrivia(s, 0) === s.length; } - const nullTransformationContext: TransformationContext = { - enableEmitNotification: noop, - enableSubstitution: noop, - endLexicalEnvironment: () => undefined, - getCompilerOptions: notImplemented, - getEmitHost: notImplemented, - getEmitResolver: notImplemented, - hoistFunctionDeclaration: noop, - hoistVariableDeclaration: noop, - isEmitNotificationEnabled: notImplemented, - isSubstitutionEnabled: notImplemented, - onEmitNode: noop, - onSubstituteNode: notImplemented, - readEmitHelpers: notImplemented, - requestEmitHelper: noop, - resumeLexicalEnvironment: noop, - startLexicalEnvironment: noop, - suspendLexicalEnvironment: noop - }; - function assignPositionsToNode(node: Node): Node { const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray); // create proxy node for non synthesized nodes diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts b/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts index b6dd679bb7..fb66a04cd5 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts @@ -6,8 +6,8 @@ //// abstract z: number; //// } //// -//// class C extends A {[| |] -//// constructor(public x: number) { super(); } +//// class C extends A {[| +//// |]constructor(public x: number) { super(); } //// y: number; //// } diff --git a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts index ede19ef570..57372dd7e8 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts @@ -8,8 +8,8 @@ //// //// } //// -//// class C3 implements C2 {[| |] -//// f2(){} +//// class C3 implements C2 {[| +//// |]f2(){} //// } verify.rangeAfterCodeFix(`f1(): void{ diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts index 4a6bb20f57..7d77c5b9af 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts @@ -7,7 +7,7 @@ //// [2]: boolean; //// } //// -//// class C implements I {[| |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` ["foo"](o: any): boolean {