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);
// 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 {
if (!type) {
if (undefinedArgumentIsError) { encounteredError = true; }
@ -2267,6 +2248,9 @@ namespace ts {
throw new Error("ESSymbol not implemented");
}
if (type.flags & TypeFlags.TypeParameter) {
if ((<TypeParameter>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(<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. */
function mapToTypeNodeArray(types: Type[]): NodeArray<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;
}
/* @internal */
export function getSynthesizedDeepClone<T extends Node>(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 <PrimaryExpression>createSynthesizedNode(SyntaxKind.ThisKeyword);
return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.ThisKeyword);
}
export function createNull() {
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.NullKeyword);
return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.NullKeyword);
}
export function createTrue() {

View file

@ -4065,7 +4065,7 @@ namespace ts {
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>;

View file

@ -3,6 +3,28 @@
/// <reference path="utilities.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.
*
@ -813,7 +835,8 @@ namespace ts {
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
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;
// 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;

View file

@ -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

View file

@ -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;
//// }

View file

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

View file

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