Merge branch 'createTypeNode2' into createTypeNode

This commit is contained in:
Arthur Ozga 2017-03-23 14:12:25 -07:00
commit bfb1bb4801
5 changed files with 178 additions and 117 deletions

View file

@ -2192,16 +2192,13 @@ namespace ts {
return result;
}
function unwrapNodeBuilderResult<T>(result: NodeBuilderResult<T>, returnValueOnError: boolean): T | undefined {
return !result.error || returnValueOnError ? result.value : undefined;
}
function getNodeBuilder(): NodeBuilder {
if (nodeBuilderCache) {
return nodeBuilderCache;
}
let encounteredError = false;
nodeBuilderCache = {
typeToTypeNode,
indexInfoToIndexSignatureDeclaration,
@ -2210,21 +2207,40 @@ namespace ts {
return nodeBuilderCache;
function typeToTypeNode(type: Type, enclosingDeclaration?: Node, emitNodeOnError?: boolean): NodeBuilderResult<TypeNode> {
let toNodeEncounteredErrorCache = encounteredError;
encounteredError = false;
function typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode {
const helper = () => typeToTypeNodeHelper(type, enclosingDeclaration, flags);
return callHelperWithErrorHandling(helper);
}
function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration {
const helper = () => indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, enclosingDeclaration, flags);
return callHelperWithErrorHandling(helper);
}
function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration {
const helper = () => signatureToSignatureDeclarationHelper(signature, kind, enclosingDeclaration, flags);
return callHelperWithErrorHandling(helper);
}
function callHelperWithErrorHandling<T extends Node>(nodeBuilderHelper: () => T): T | undefined {
const encounteredErrorCache = encounteredError;
const resultingNode = nodeBuilderHelper();
const result = encounteredError ? undefined : resultingNode;
encounteredError = encounteredErrorCache;
return result;
}
function typeToTypeNodeHelper(type: Type, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeNode {
let inObjectTypeLiteral = false;
let checkAlias = true;
let symbolStack: Symbol[] = undefined;
const resultingNode = typeToTypeNodeWorker(type);
const result = encounteredError && !emitNodeOnError ? undefined : resultingNode;
encounteredError = toNodeEncounteredErrorCache;
return result;
return typeToTypeNodeWorker(type);
function typeToTypeNodeWorker(type: Type): NodeBuilderResult<TypeNode> {
function typeToTypeNodeWorker(type: Type): TypeNode {
if (!type) {
encounteredError = true;
// TODO(aozgaa): should we return implict any (undefined) or explicit any (keywordtypenode)?
return undefined;
}
@ -2241,7 +2257,7 @@ namespace ts {
return createKeywordTypeNode(SyntaxKind.BooleanKeyword);
}
if (type.flags & TypeFlags.Enum) {
const name = symbolToName(type.symbol, enclosingDeclaration);
const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags);
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
}
if (type.flags & (TypeFlags.StringLiteral)) {
@ -2254,7 +2270,7 @@ namespace ts {
return (<IntrinsicType>type).intrinsicName === "true" ? createTrue() : createFalse();
}
if (type.flags & TypeFlags.EnumLiteral) {
const name = symbolToName(type.symbol, enclosingDeclaration);
const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags);
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
}
if (type.flags & TypeFlags.Void) {
@ -2277,7 +2293,7 @@ namespace ts {
}
if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) {
if (inObjectTypeLiteral) {
encounteredError = true;
encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowThisInObjectLiteral);
}
return createThis();
}
@ -2286,22 +2302,22 @@ namespace ts {
if (objectFlags & ObjectFlags.Reference) {
Debug.assert(!!(type.flags & TypeFlags.Object));
return typeReferenceToTypeReferenceNode(<TypeReference>type);
return typeReferenceToTypeNode (<TypeReference>type);
}
if (objectFlags & ObjectFlags.ClassOrInterface) {
Debug.assert(!!(type.flags & TypeFlags.Object));
const name = symbolToName(type.symbol, enclosingDeclaration);
const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags);
// TODO(aozgaa): handle type arguments.
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
}
if (type.flags & TypeFlags.TypeParameter) {
const name = symbolToName(type.symbol, enclosingDeclaration);
const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags);
// Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
}
if (checkAlias && type.aliasSymbol) {
const name = symbolToName(type.aliasSymbol, enclosingDeclaration);
const name = symbolToName(type.aliasSymbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags);
const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments);
return createTypeReferenceNode(name, typeArgumentNodes);
}
@ -2335,15 +2351,16 @@ namespace ts {
Debug.fail("Should be unreachable.");
function mapToTypeNodeArray(types: Type[]): NodeArray<TypeNode> {
return types && asNodeArray(types.map(typeToTypeNodeWorker) as TypeNode[]);
return types && asNodeArray(types.map(typeToTypeNodeWorker).filter(node => !!node));
}
function createMappedTypeNodeFromType(type: MappedType) {
Debug.assert(!!(type.flags & TypeFlags.Object));
const typeParameter = getTypeParameterFromMappedType(<MappedType>type);
const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration);
const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration, flags);
const templateTypeNode = typeToTypeNodeWorker(getTemplateTypeFromMappedType(<MappedType>type));
const templateType = getTemplateTypeFromMappedType(<MappedType>type)
const templateTypeNode = templateType && typeToTypeNodeWorker(templateType);
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;
@ -2364,7 +2381,7 @@ namespace ts {
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// The specified symbol flags need to be reinterpreted as type flags
const entityName = symbolToName(typeAlias, enclosingDeclaration);
const entityName = symbolToName(typeAlias, enclosingDeclaration, /*expectsIdentifier*/ false, flags);
return createTypeReferenceNode(entityName, /*typeArguments*/ undefined);
}
else {
@ -2417,11 +2434,11 @@ namespace ts {
if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
const signature = resolved.callSignatures[0];
return <FunctionTypeNode>signatureToSignatureDeclaration(signature, SyntaxKind.FunctionType, enclosingDeclaration, emitNodeOnError);
return <FunctionTypeNode>signatureToSignatureDeclarationHelper(signature, SyntaxKind.FunctionType, enclosingDeclaration, flags);
}
if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
const signature = resolved.constructSignatures[0];
return <ConstructorTypeNode>signatureToSignatureDeclaration(signature, SyntaxKind.ConstructorType, enclosingDeclaration, emitNodeOnError);
return <ConstructorTypeNode>signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructorType, enclosingDeclaration, flags);
}
}
@ -2435,12 +2452,12 @@ namespace ts {
function createTypeQueryNodeFromType(type: Type) {
const symbol = type.symbol;
if (symbol) {
const entityName = symbolToName(symbol, enclosingDeclaration);
const entityName = symbolToName(symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags);
return createTypeQueryNode(entityName);
}
}
function typeReferenceToTypeReferenceNode(type: TypeReference) {
function typeReferenceToTypeNode(type: TypeReference) {
const typeArguments: Type[] = type.typeArguments || emptyArray;
if (type.target === globalArrayType) {
const elementType = typeToTypeNodeWorker(typeArguments[0]);
@ -2465,7 +2482,7 @@ namespace ts {
// When type parameters are their own type arguments for the whole group (i.e. we have
// the default outer type arguments), we don't show the group.
if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) {
const qualifiedNamePart = symbolToName(parent, enclosingDeclaration, /*mustBeIdentifier*/ true);
const qualifiedNamePart = symbolToName(parent, enclosingDeclaration, /*expectsIdentifier*/ true, flags);
if (!qualifiedName) {
qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined);
}
@ -2478,7 +2495,7 @@ namespace ts {
}
}
let entityName: EntityName = undefined;
const nameIdentifier = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true);
const nameIdentifier = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ true, flags);
if (qualifiedName) {
Debug.assert(!qualifiedName.right);
qualifiedName.right = nameIdentifier;
@ -2496,16 +2513,16 @@ namespace ts {
function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] {
const typeElements: TypeElement[] = [];
for (const signature of resolvedType.callSignatures) {
typeElements.push(<CallSignatureDeclaration>signatureToSignatureDeclaration(signature, SyntaxKind.CallSignature, enclosingDeclaration, emitNodeOnError));
typeElements.push(<CallSignatureDeclaration>signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature, enclosingDeclaration, flags));
}
for (const signature of resolvedType.constructSignatures) {
typeElements.push(<ConstructSignatureDeclaration>signatureToSignatureDeclaration(signature, SyntaxKind.ConstructSignature, enclosingDeclaration, emitNodeOnError));
typeElements.push(<ConstructSignatureDeclaration>signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, enclosingDeclaration, flags));
}
if (resolvedType.stringIndexInfo) {
typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration, emitNodeOnError));
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration, flags));
}
if (resolvedType.numberIndexInfo) {
typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration, emitNodeOnError));
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration, flags));
}
const properties = resolvedType.properties;
@ -2524,17 +2541,20 @@ namespace ts {
if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) {
const signatures = getSignaturesOfType(propertyType, SignatureKind.Call);
for (const signature of signatures) {
const methodDeclaration = <MethodSignature>signatureToSignatureDeclaration(signature, SyntaxKind.MethodSignature, enclosingDeclaration, emitNodeOnError);
const methodDeclaration = <MethodSignature>signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, enclosingDeclaration, flags);
methodDeclaration.name = propertyName;
methodDeclaration.questionToken = optionalToken;
typeElements.push(methodDeclaration);
}
}
else {
// TODO(aozgaa): should we create a node with explicit or implict any?
const propertyTypeNode = propertyType ? typeToTypeNodeWorker(propertyType) : createKeywordTypeNode(SyntaxKind.AnyKeyword);
typeElements.push(createPropertySignature(
propertyName,
optionalToken,
typeToTypeNodeWorker(propertyType),
propertyTypeNode,
/*initializer*/undefined));
}
}
@ -2543,10 +2563,7 @@ namespace ts {
}
}
function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node, emitNodeOnError?: boolean): IndexSignatureDeclaration {
const encounteredErrorCache = encounteredError;
encounteredError = false;
function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node, flags: NodeBuilderFlags): IndexSignatureDeclaration {
const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword);
const name = getNameFromIndexInfo(indexInfo);
@ -2558,55 +2575,46 @@ namespace ts {
/*questionToken*/ undefined,
indexerTypeNode,
/*initializer*/ undefined);
const typeNode = typeToTypeNode(indexInfo.type, enclosingDeclaration, emitNodeOnError);
const result = !encounteredError || emitNodeOnError ? createIndexSignatureDeclaration(
const typeNode = typeToTypeNodeHelper(indexInfo.type, enclosingDeclaration, flags);
return createIndexSignatureDeclaration(
[indexingParameter],
typeNode,
/*decorators*/ undefined,
indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined)
: undefined;
encounteredError = encounteredErrorCache;
return result;
indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined);
}
function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, emitNodeOnError?: boolean): SignatureDeclaration {
const encounteredErrorCache = encounteredError;
encounteredError = false;
function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node, flags: NodeBuilderFlags): SignatureDeclaration {
const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration));
const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration));
const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration, flags));
const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration, flags));
const type = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature));
const result = !encounteredError || emitNodeOnError ? createSignatureDeclaration(kind, typeParameters, parameters, type) : undefined;
encounteredError = encounteredErrorCache;
return result;
return createSignatureDeclaration(kind, typeParameters, parameters, type);
function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined {
const typeNode = typeToTypeNode(type, enclosingDeclaration, emitNodeOnError);
// Note, this call will *not* mark encounteredError.
const typeNode = typeToTypeNode(type, enclosingDeclaration);
return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined;
}
}
function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration?: Node, returnNodeOnError?: boolean): TypeParameterDeclaration {
function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeParameterDeclaration {
if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) {
return undefined;
}
const constraint = typeToTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration);
const defaultParameter = typeToTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration);
let toNodeEncounteredErrorCache = encounteredError;
encounteredError = false;
const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true);
let result = encounteredError && !returnNodeOnError ? undefined : createTypeParameterDeclaration(name, constraint, defaultParameter);
encounteredError = toNodeEncounteredErrorCache;
return result;
const constraint = getConstraintFromTypeParameter(type);
const constraintNode = constraint && typeToTypeNodeHelper(constraint, enclosingDeclaration, flags);
const defaultParameter = getDefaultFromTypeParameter(type);
const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, enclosingDeclaration, flags);
const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ true, flags);
return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
}
function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration?: Node): ParameterDeclaration {
function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration: Node, flags: NodeBuilderFlags): ParameterDeclaration {
const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration;
const parameterType = getTypeOfSymbol(parameterSymbol);
const parameterTypeNode = typeToTypeNode(parameterType, enclosingDeclaration);
const parameterTypeNode = typeToTypeNodeHelper(parameterType, enclosingDeclaration, flags);
// TODO(aozgaa): check initializer accessibility correctly.
const parameterNode = createParameter(
parameterDeclaration.decorators,
@ -2620,19 +2628,17 @@ namespace ts {
return parameterNode;
}
function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: true): Identifier;
function symbolToName(symbol: Symbol, enclosingDeclaration?: Node, mustBeIdentifier?: false): EntityName;
function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: boolean | undefined): EntityName {
function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: true, flags: NodeBuilderFlags): Identifier;
function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: false, flags: NodeBuilderFlags): EntityName;
function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: boolean, flags: NodeBuilderFlags): EntityName {
let parentSymbol: Symbol;
let meaning: SymbolFlags;
// Get qualified name if the symbol is not a type parameter
// and there is an enclosing declaration.
// Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
let chain: Symbol[];
const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter;
if (!isTypeParameter && enclosingDeclaration) {
chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true);
// TODO: check whether type pointed to by symbol requires type arguments to be printed.
Debug.assert(chain && chain.length > 0);
}
else {
@ -2640,10 +2646,9 @@ namespace ts {
}
parentSymbol = undefined;
if (mustBeIdentifier && chain.length !== 1) {
encounteredError = true;
// TODO: failing to get an identifier when we expect one generates an unprintable node.
// Should error handling be more severe?
if (expectsIdentifier && chain.length !== 1) {
encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier);
}
return createEntityNameFromSymbolChain(chain, chain.length - 1);
@ -2653,7 +2658,7 @@ namespace ts {
const symbol = chain[index];
let typeParameterString = "";
if (index > 0) {
// TODO: is the parentSymbol wrong?
const parentSymbol = chain[index - 1];
let typeParameters: TypeParameter[];
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
@ -2666,7 +2671,8 @@ namespace ts {
}
}
if (typeParameters && typeParameters.length > 0) {
encounteredError = true;
encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowTypeParameterInQualifiedName);;
const writer = getSingleLineStringWriter();
const displayBuilder = getSymbolDisplayBuilder();
displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, 0);
@ -2724,7 +2730,7 @@ namespace ts {
if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) {
return declarationNameToString((<VariableDeclaration>declaration.parent).name);
}
encounteredError = true;
encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowAnonymousIdentifier);
switch (declaration.kind) {
case SyntaxKind.ClassExpression:
return "(Anonymous class)";

View file

@ -378,28 +378,65 @@ namespace ts {
}
// TODO: Split according to AST nodes.
export function createSignatureDeclaration<T extends SignatureDeclaration>(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): T;
export function createSignatureDeclaration<T extends SignatureDeclaration & TypeElement>(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): T;
export function createSignatureDeclaration<T extends SignatureDeclaration & TypeElement>(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name?: string | PropertyName, questionToken?: QuestionToken): T {
const signatureDeclaration = createSynthesizedNode(kind) as T;
export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration;
signatureDeclaration.typeParameters = asNodeArray(typeParameters);
signatureDeclaration.parameters = asNodeArray(parameters);
signatureDeclaration.type = type;
signatureDeclaration.name = asName(name);
signatureDeclaration.questionToken = questionToken;
return signatureDeclaration;
}
// TODO: figure out right type annotation for this function.
export function updateSignatureDeclaration<T extends SignatureDeclaration>(node: T, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): T;
export function updateSignatureDeclaration<T extends SignatureDeclaration & TypeElement>(node: T, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined): T;
export function updateSignatureDeclaration<T extends SignatureDeclaration & TypeElement>(node: T, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined, name?: PropertyName, questionToken?: QuestionToken): T {
export function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
: node;
}
export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode {
return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode;
}
export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): FunctionTypeNode {
return <FunctionTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode {
return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode;
}
export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): ConstructorTypeNode {
return <ConstructorTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration {
return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration;
}
export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): CallSignatureDeclaration {
return <CallSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration {
return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration;
}
export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): ConstructSignatureDeclaration {
return <ConstructSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature{
const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature;
methodSignature.name = asName(name);
methodSignature.questionToken = questionToken;
return methodSignature;
}
export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined, name?: PropertyName, questionToken?: QuestionToken): MethodSignature {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
|| node.name !== name
|| node.questionToken !== questionToken
? updateNode(createSignatureDeclaration<T>(node.kind, typeParameters, parameters, type, name, questionToken), node)
? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
: node;
}
@ -502,7 +539,7 @@ namespace ts {
: node;
}
export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
export function createMethodDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
const node = <MethodDeclaration>createSynthesizedNode(SyntaxKind.MethodDeclaration);
node.decorators = asNodeArray(decorators);
node.modifiers = asNodeArray(modifiers);
@ -525,7 +562,7 @@ namespace ts {
|| node.parameters !== parameters
|| node.type !== type
|| node.body !== body
? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
? updateNode(createMethodDeclaration(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
: node;
}

View file

@ -2473,11 +2473,12 @@ namespace ts {
getNonNullableType(type: Type): Type;
/** Note that the resulting nodes cannot be checked. */
typeToTypeNode(type: Type, enclosingDeclaration?: Node, returnNodeOnError?: boolean): TypeNode;
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode;
/** Note that the resulting nodes cannot be checked. */
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, returnNodeOnError?: boolean): SignatureDeclaration;
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration;
/** Note that the resulting nodes cannot be checked. */
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, returnNodeOnError?: boolean): IndexSignatureDeclaration;
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration;
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
getSymbolAtLocation(node: Node): Symbol;
@ -2530,18 +2531,20 @@ namespace ts {
/* @internal */ getTypeCount(): number;
}
/** Note that the resulting nodes cannot be checked. */
/** Note that any resulting nodes cannot be checked. */
/* @internal */
export interface NodeBuilder {
typeToTypeNode(type: Type, enclosingDeclaration?: Node, returnNodeOnError?: boolean): NodeBuilderResult<TypeNode>;
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node): NodeBuilderResult<SignatureDeclaration>;
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): NodeBuilderResult<IndexSignatureDeclaration>;
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode;
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration;
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration;
}
/* @internal */
export interface NodeBuilderResult<T> {
value: T;
error?: boolean;
export enum NodeBuilderFlags {
None = 0,
allowThisInObjectLiteral = 1 << 0,
allowQualifedNameInPlaceOfIdentifier = 1 << 1,
allowTypeParameterInQualifiedName = 1 << 2,
allowAnonymousIdentifier = 1 << 3
}
export interface SymbolDisplayBuilder {

View file

@ -260,21 +260,36 @@ namespace ts {
// Signatures and Signature Elements
case SyntaxKind.FunctionType:
return updateFunctionTypeNode(<FunctionTypeNode>node,
nodesVisitor((<FunctionTypeNode>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<FunctionTypeNode>node).parameters, visitor, context, nodesVisitor),
visitNode((<FunctionTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.ConstructorType:
return updateConstructorTypeNode(<ConstructorTypeNode>node,
nodesVisitor((<ConstructorTypeNode>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<ConstructorTypeNode>node).parameters, visitor, context, nodesVisitor),
visitNode((<ConstructorTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.CallSignature:
return updateCallSignatureDeclaration(<CallSignatureDeclaration>node,
nodesVisitor((<CallSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<CallSignatureDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<CallSignatureDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.ConstructSignature:
return updateSignatureDeclaration(<SignatureDeclaration>node,
nodesVisitor((<SignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<SignatureDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<SignatureDeclaration>node).type, visitor, isTypeNode));
return updateConstructSignatureDeclaration(<ConstructSignatureDeclaration>node,
nodesVisitor((<ConstructSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<ConstructSignatureDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<ConstructSignatureDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.MethodSignature:
return updateSignatureDeclaration(<SignatureDeclaration & TypeElement>node,
nodesVisitor((<SignatureDeclaration & TypeElement>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<SignatureDeclaration & TypeElement>node).parameters, visitor, context, nodesVisitor),
visitNode((<SignatureDeclaration & TypeElement>node).type, visitor, isTypeNode),
visitNode((<SignatureDeclaration & TypeElement>node).name, visitor, isPropertyName),
visitNode((<SignatureDeclaration & TypeElement>node).questionToken, tokenVisitor, isToken));
return updateMethodSignature(<MethodSignature>node,
nodesVisitor((<MethodSignature>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<MethodSignature>node).parameters, visitor, context, nodesVisitor),
visitNode((<MethodSignature>node).type, visitor, isTypeNode),
visitNode((<MethodSignature>node).name, visitor, isPropertyName),
visitNode((<MethodSignature>node).questionToken, tokenVisitor, isToken));
case SyntaxKind.IndexSignature:
return updateIndexSignatureDeclaration(<IndexSignatureDeclaration>node,

View file

@ -100,7 +100,7 @@ namespace ts.codefix {
if (declarations.length === 1) {
Debug.assert(signatures.length === 1);
const signature = signatures[0];
const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration;
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration);
signatureDeclaration.modifiers = modifiers;
signatureDeclaration.name = name;
signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined;
@ -111,7 +111,7 @@ namespace ts.codefix {
let signatureDeclarations = [];
for (let i = 0; i < signatures.length; i++) {
const signature = signatures[i];
const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration;
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration);
signatureDeclaration.modifiers = modifiers;
signatureDeclaration.name = name;
signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined;
@ -120,7 +120,7 @@ namespace ts.codefix {
if (declarations.length > signatures.length) {
let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration);
const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration;
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration);
signatureDeclaration.modifiers = modifiers;
signatureDeclaration.name = name;
signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined;
@ -197,7 +197,7 @@ namespace ts.codefix {
}
export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) {
return createMethod(
return createMethodDeclaration(
/*decorators*/ undefined,
modifiers,
/*asteriskToken*/ undefined,