* added signature factory/visitor entry
This commit is contained in:
Arthur Ozga 2017-03-15 18:09:55 -07:00
parent a4b981af16
commit 0a2d7a7f94
10 changed files with 166 additions and 15 deletions

View file

@ -2322,10 +2322,18 @@ namespace ts {
if (objectFlags & ObjectFlags.Mapped) {
Debug.assert(!!(type.flags & TypeFlags.Object));
// const typeParameter = getTypeParameterFromMappedType(<MappedType>type);
// TODO: does typeParameter have the same constraint or do we need to overwrite it somehow?
const typeParameter = getTypeParameterFromMappedType(<MappedType>type);
// const constraintType = getConstraintTypeFromMappedType(<MappedType>type);
// const templateType = getTemplateTypeFromMappedType(<MappedType>type);
throw new Error("Mapped types not implemented");
const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter);
const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(<MappedType>type));
const readonlyToken = (<MappedType>type).declaration && (<MappedType>type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined;
const questionToken = (<MappedType>type).declaration && (<MappedType>type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined;
// TODO: test.
return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
}
if (objectFlags & ObjectFlags.Anonymous) {
@ -2334,6 +2342,7 @@ namespace ts {
if (!type.symbol) {
// Anonymous types without symbols are literals.
// TODO: handle this case correctly.
// TODO: test.
noop();
}
@ -2343,9 +2352,11 @@ namespace ts {
// TODO: string or number literal here or above?
if (type.flags & TypeFlags.Index) {
// TODO: implement and test.
throw new Error("index not implemented");
}
if (type.flags & TypeFlags.IndexedAccess) {
// TODO: implement and test.
throw new Error("indexed access not implemented");
}
@ -2414,7 +2425,6 @@ namespace ts {
}
function createTypeLiteralNodeFromType(type: ObjectType) {
// TODO: do we need to do something for mapped types here???
const resolvedType = resolveStructuredTypeMembers(type);
const newMembers = createTypeNodesFromResolvedType(resolvedType);
return createTypeLiteralNode(newMembers);
@ -2446,21 +2456,29 @@ namespace ts {
}
const kind = oldDeclaration.kind;
const memberName = symbolToString(memberSymbol);
const memberName = getSynthesizedDeepClone(oldDeclaration.name);
const memberType = getTypeOfSymbol(memberSymbol);
switch (kind) {
case SyntaxKind.PropertySignature:
const optional = !!oldDeclaration.questionToken;
const typeOfOldMember = getTypeOfSymbol(memberSymbol);
typeElements.push(createPropertySignature(
createIdentifier(memberName)
memberName
, optional ? createToken(SyntaxKind.QuestionToken) : undefined
, createTypeNode(typeOfOldMember)
, createTypeNode(memberType)
, /*initializer*/undefined));
break;
case SyntaxKind.MethodSignature:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
const signatureType = getSignaturesOfSymbol(memberSymbol);
signatureType
createSignatureDeclaration
throw new Error("signature problems.");
// name ?: PropertyName;
// typeParameters ?: NodeArray<TypeParameterDeclaration>;
// parameters: NodeArray<ParameterDeclaration>;
// type ?: TypeNode;
case SyntaxKind.IndexSignature:
throw new Error("type literal constituent not implemented.");
default:

View file

@ -255,6 +255,22 @@ namespace ts {
: node;
}
export function createSignatureDeclaration<T extends SignatureDeclaration>(kind: SyntaxKind, name: string | PropertyName | undefined, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): T {
const signatureDeclaration = createSynthesizedNode(kind) as T;
signatureDeclaration.name = asName(name);
signatureDeclaration.typeParameters = asNodeArray(typeParameters);
signatureDeclaration.type = type;
return signatureDeclaration;
}
export function updateSignatureDeclaration<T extends SignatureDeclaration>(node: T, name: string | PropertyName | undefined, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): T {
return node.name !== name
|| node.typeParameters !== typeParameters
|| node.type !== type
? <T>updateNode(createSignatureDeclaration(node.kind, name, typeParameters, parameters, type), node)
: node;
}
export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: NodeArray<TypeNode> | undefined) {
const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode;
@ -321,6 +337,24 @@ namespace ts {
: node;
}
export function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode {
const mappedTypeNode = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode;
mappedTypeNode.readonlyToken = readonlyToken;
mappedTypeNode.typeParameter = typeParameter;
mappedTypeNode.questionToken = questionToken;
mappedTypeNode.type = type;
return mappedTypeNode;
}
export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode {
return node.readonlyToken !== readonlyToken
|| node.typeParameter !== typeParameter
|| node.questionToken !== questionToken
|| node.type !== type
? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
: node;
}
// Type Declarations
export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) {

View file

@ -856,6 +856,7 @@ namespace ts {
| SyntaxKind.BooleanKeyword
| SyntaxKind.StringKeyword
| SyntaxKind.SymbolKeyword
| SyntaxKind.ThisKeyword
| SyntaxKind.VoidKeyword
| SyntaxKind.UndefinedKeyword
| SyntaxKind.NullKeyword

View file

@ -3717,10 +3717,14 @@ namespace ts {
return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode)
|| kind === SyntaxKind.AnyKeyword
|| kind === SyntaxKind.NumberKeyword
|| kind === SyntaxKind.ObjectKeyword
|| kind === SyntaxKind.BooleanKeyword
|| kind === SyntaxKind.StringKeyword
|| kind === SyntaxKind.SymbolKeyword
|| kind === SyntaxKind.ThisKeyword
|| kind === SyntaxKind.VoidKeyword
|| kind === SyntaxKind.UndefinedKeyword
|| kind === SyntaxKind.NullKeyword
|| kind === SyntaxKind.NeverKeyword
|| kind === SyntaxKind.ExpressionWithTypeArguments;
}

View file

@ -258,13 +258,23 @@ namespace ts {
return updateComputedPropertyName(<ComputedPropertyName>node,
visitNode((<ComputedPropertyName>node).expression, visitor, isExpression));
// Signature elements
// Signatures and Signature Elements
case SyntaxKind.FunctionType:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.MethodSignature:
return updateSignatureDeclaration(<SignatureDeclaration>node
, visitNode((<SignatureDeclaration>node).name, visitor, isPropertyName)
, nodesVisitor((<SignatureDeclaration>node).typeParameters, visitor, isTypeParameter)
, nodesVisitor((<SignatureDeclaration>node).parameters, visitor, isParameter)
, visitNode((<SignatureDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.IndexSignature:
return updateIndexSignatureDeclaration(<IndexSignatureDeclaration>node
, nodesVisitor((<IndexSignatureDeclaration>node).parameters, visitor)
, visitNode((<IndexSignatureDeclaration>node).type, visitor)
, nodesVisitor((<IndexSignatureDeclaration>node).decorators, visitor, isDecorator)
, nodesVisitor((<IndexSignatureDeclaration>node).modifiers, visitor, isModifier));
, nodesVisitor((<IndexSignatureDeclaration>node).parameters, visitor)
, visitNode((<IndexSignatureDeclaration>node).type, visitor, isTypeNode)
, nodesVisitor((<IndexSignatureDeclaration>node).decorators, visitor, isDecorator)
, nodesVisitor((<IndexSignatureDeclaration>node).modifiers, visitor, isModifier));
case SyntaxKind.Parameter:
return updateParameter(<ParameterDeclaration>node,

View file

@ -1673,7 +1673,7 @@ namespace FourSlash {
// We get back a set of edits, but langSvc.editScript only accepts one at a time. Use this to keep track
// of the incremental offset from each edit to the next. Assumption is that these edit ranges don't overlap
let runningOffset = 0;
edits = edits.sort((a, b) => a.span.start - b.span.start);
edits = ts.stableSort(edits, (a, b) => a.span.start - b.span.start);
// Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters
const oldContent = this.getFileContent(fileName);

View file

@ -0,0 +1,14 @@
/// <reference path='fourslash.ts' />
// @lib: es2017
//// /** interface prefix */
//// interface /**interface name prefix */ I /**open-brace prefix*/{
//// /** property prefix*/ x /**colon prefix*/: /**number prefix*/ number;
////
//// /**close-brace prefix*/ }
//// class C implements I {[| |]}
verify.rangeAfterCodeFix(`
x: number;
`);

View file

@ -17,7 +17,6 @@
//// [Symbol.toStringTag]: string;
//// [Symbol.unscopables]: any;
//// }
////
//// class C implements I<number> {[| |]}
verify.rangeAfterCodeFix(`

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// interface I {
//// x: {};
//// }
////
//// class C implements I {[|
//// |]constructor() { }
//// }
verify.rangeAfterCodeFix(`
x: {};
`);

View file

@ -0,0 +1,58 @@
/// <reference path='fourslash.ts' />
// @lib: es2017
//// /** asdf */
//// interface I {
//// 1;
//// 2;
//// 3;
//// 4;
//// 5;
//// 6;
//// 7;
//// 8;
//// 9;
//// 10;
//// 11;
//// 12;
//// 13;
//// 14;
//// 15;
//// 16;
//// 17;
//// 18;
//// 19;
//// 20;
//// 21;
//// 22;
//// /** a nice safe prime */
//// 23;
//// }
//// class C implements I {[| |]}
verify.rangeAfterCodeFix(`
1: any;
2: any;
3: any;
4: any;
5: any;
6: any;
7: any;
8: any;
9: any;
10: any;
11: any;
12: any;
13: any;
14: any;
15: any;
16: any;
17: any;
18: any;
19: any;
20: any;
21: any;
22: any;
23: any;
`);