type literals, properties only

This commit is contained in:
Arthur Ozga 2017-03-13 09:18:40 -07:00
parent 6fe59f3450
commit f0b4efe94f
9 changed files with 97 additions and 73 deletions

View file

@ -2196,25 +2196,6 @@ namespace ts {
return createTypeNodeWorker(type); 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(<TypeParameter>type)) as TypeNode;
// const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(<TypeParameter>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 { function createTypeNodeWorker(type: Type): TypeNode {
if (!type) { if (!type) {
if (undefinedArgumentIsError) { encounteredError = true; } if (undefinedArgumentIsError) { encounteredError = true; }
@ -2267,6 +2248,9 @@ namespace ts {
throw new Error("ESSymbol not implemented"); throw new Error("ESSymbol not implemented");
} }
if (type.flags & TypeFlags.TypeParameter) { if (type.flags & TypeFlags.TypeParameter) {
if ((<TypeParameter>type).isThisType) {
return createThis();
}
throw new Error("Type Parameter declarations only handled in other worker."); throw new Error("Type Parameter declarations only handled in other worker.");
} }
if (type.flags & TypeFlags.Union) { if (type.flags & TypeFlags.Union) {
@ -2332,27 +2316,12 @@ namespace ts {
// return typeSymbolAccessibility === SymbolAccessibility.Accessible // return typeSymbolAccessibility === SymbolAccessibility.Accessible
// && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); // && (!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); // const objectFlags = getObjectFlags(type);
// if (objectFlags & ObjectFlags.ClassOrInterface) { // if (objectFlags & ObjectFlags.ClassOrInterface) {
// // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, // // 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. // // type must be an anonymous class or interface.
// return false; // 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) { if (objectFlags & ObjectFlags.Mapped) {
Debug.assert(!!(type.flags & TypeFlags.Object)); Debug.assert(!!(type.flags & TypeFlags.Object));
@ -2370,25 +2339,68 @@ namespace ts {
// mapToTypeDeclarationsArray(type) // 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;
// const members = type.symbol.members; const newMembers: TypeElement[] = [];
// let allVisible = true; memberLoop: for(const key in members){
// members && members.forEach((member) => { const oldMember = members.get(key);
// const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration); const name = getNameOfSymbol(oldMember);
// allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false); const oldDeclaration = oldMember.declarations && oldMember.declarations[0] as TypeElement;
// }); if(!oldDeclaration) {
// return allVisible; 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."); 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(<TypeParameter>type)) as TypeNode;
// const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(<TypeParameter>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. */ /** Note that mapToTypeNodeArray(undefined) === undefined. */
function mapToTypeNodeArray(types: Type[]): NodeArray<TypeNode> { function mapToTypeNodeArray(types: Type[]): NodeArray<TypeNode> {
return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]);
} }
// /** Note that mapToTypeNodeArray(undefined) === undefined. */
// function mapToTypeParameterArray(types: Type[]): NodeArray<TypeNode> {
// return asNodeArray(types && types.map(createTypeParameterDeclarationFromType) as TypeNode[]);
// }
} }
} }

View file

@ -67,6 +67,14 @@ namespace ts {
return clone; return clone;
} }
/* @internal */
export function getSynthesizedDeepClone<T extends Node>(node: T | undefined): T {
if (node === undefined) {
return undefined;
}
return getSynthesizedClone(visitEachChild(node, getSynthesizedClone, nullTransformationContext));
}
// Literals // Literals
export function createLiteral(value: string): StringLiteral; export function createLiteral(value: string): StringLiteral;
@ -173,11 +181,11 @@ namespace ts {
} }
export function createThis() { export function createThis() {
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.ThisKeyword); return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.ThisKeyword);
} }
export function createNull() { export function createNull() {
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.NullKeyword); return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.NullKeyword);
} }
export function createTrue() { export function createTrue() {

View file

@ -4065,7 +4065,7 @@ namespace ts {
export type Transformer<T extends Node> = (node: T) => T; export type Transformer<T extends Node> = (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<Node>; export type Visitor = (node: Node) => VisitResult<Node>;

View file

@ -3,6 +3,28 @@
/// <reference path="utilities.ts" /> /// <reference path="utilities.ts" />
namespace ts { 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. * Visits a Node using the supplied visitor, possibly returning a new Node in its place.
* *
@ -813,7 +835,8 @@ namespace ts {
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression)); visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
default: default:
return node; throw new Error("not handled");
// return node;
} }
} }

View file

@ -51,6 +51,7 @@ namespace ts.codefix {
} }
const declaration = declarations[0] as Declaration; 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 name = declaration.name ? declaration.name.getText() : undefined;
const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration));
const modifiers = visibilityModifier ? [visibilityModifier] : undefined; const modifiers = visibilityModifier ? [visibilityModifier] : undefined;

View file

@ -341,26 +341,6 @@ namespace ts.textChanges {
return skipTrivia(s, 0) === s.length; 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 { function assignPositionsToNode(node: Node): Node {
const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray); const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray);
// create proxy node for non synthesized nodes // create proxy node for non synthesized nodes

View file

@ -6,8 +6,8 @@
//// abstract z: number; //// abstract z: number;
//// } //// }
//// ////
//// class C extends A {[| |] //// class C extends A {[|
//// constructor(public x: number) { super(); } //// |]constructor(public x: number) { super(); }
//// y: number; //// y: number;
//// } //// }

View file

@ -8,8 +8,8 @@
//// ////
//// } //// }
//// ////
//// class C3 implements C2 {[| |] //// class C3 implements C2 {[|
//// f2(){} //// |]f2(){}
//// } //// }
verify.rangeAfterCodeFix(`f1(): void{ verify.rangeAfterCodeFix(`f1(): void{

View file

@ -7,7 +7,7 @@
//// [2]: boolean; //// [2]: boolean;
//// } //// }
//// ////
//// class C implements I {[| |]} //// class C implements I {[| |]}
verify.rangeAfterCodeFix(` verify.rangeAfterCodeFix(`
["foo"](o: any): boolean { ["foo"](o: any): boolean {