Function and constructor types in the syntax tree.

This commit is contained in:
Cyrus Najmabadi 2014-11-14 16:19:10 -08:00
parent bdfb5697af
commit d948510425
4 changed files with 64 additions and 16 deletions

View file

@ -93,7 +93,9 @@ module ts {
return (<Identifier>node.name).text;
}
switch (node.kind) {
case SyntaxKind.ConstructorType:
case SyntaxKind.Constructor: return "__constructor";
case SyntaxKind.FunctionType:
case SyntaxKind.CallSignature: return "__call";
case SyntaxKind.ConstructSignature: return "__new";
case SyntaxKind.IndexSignature: return "__index";
@ -114,8 +116,11 @@ module ts {
}
// Report errors every position with duplicate declaration
// Report errors on previous encountered declarations
var message = symbol.flags & SymbolFlags.BlockScopedVariable ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0;
forEach(symbol.declarations, (declaration) => {
var message = symbol.flags & SymbolFlags.BlockScopedVariable
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
: Diagnostics.Duplicate_identifier_0;
forEach(symbol.declarations, declaration => {
file.semanticErrors.push(createDiagnosticForNode(declaration.name, message, getDisplayName(declaration)));
});
file.semanticErrors.push(createDiagnosticForNode(node.name, message, getDisplayName(node)));
@ -233,6 +238,8 @@ module ts {
declareModuleMember(node, symbolKind, symbolExcludes);
break;
}
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
@ -294,6 +301,13 @@ module ts {
}
}
function bindFunctionOrConstructorType(node: SignatureDeclaration) {
var symbolKind = node.kind === SyntaxKind.FunctionType ? SymbolFlags.CallSignature : SymbolFlags.ConstructSignature;
var symbol = createSymbol(symbolKind, getDeclarationName(node));
addDeclarationToSymbol(symbol, node, symbolKind);
bindChildren(node, symbolKind, /*isBlockScopeContainer:*/ false);
}
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) {
var symbol = createSymbol(symbolKind, name);
addDeclarationToSymbol(symbol, node, symbolKind);
@ -358,12 +372,12 @@ module ts {
case SyntaxKind.CallSignature:
bindDeclaration(<Declaration>node, SymbolFlags.CallSignature, 0, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.Method:
bindDeclaration(<Declaration>node, SymbolFlags.Method, SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.ConstructSignature:
bindDeclaration(<Declaration>node, SymbolFlags.ConstructSignature, 0, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.Method:
bindDeclaration(<Declaration>node, SymbolFlags.Method, SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.IndexSignature:
bindDeclaration(<Declaration>node, SymbolFlags.IndexSignature, 0, /*isBlockScopeContainer*/ false);
break;
@ -379,6 +393,12 @@ module ts {
case SyntaxKind.SetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
bindFunctionOrConstructorType(<SignatureDeclaration>node);
break;
case SyntaxKind.TypeLiteral:
bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type", /*isBlockScopeContainer*/ false);
break;

View file

@ -2523,6 +2523,8 @@ module ts {
for (var i = 0, len = symbol.declarations.length; i < len; i++) {
var node = symbol.declarations[i];
switch (node.kind) {
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.Method:
case SyntaxKind.Constructor:
@ -2961,6 +2963,21 @@ module ts {
return links.resolvedType;
}
function getTypefromFunctionOrConstructorTypeNode(node: SignatureDeclaration): Type {
var links = getNodeLinks(node);
if (!links.resolvedType) {
var symbol = new Symbol(SymbolFlags.TypeLiteral, "__type");
symbol.members = {};
symbol.members[node.kind === SyntaxKind.FunctionType ? "__call" : "__new"] = node.symbol;
symbol.declarations = [node.symbol.declarations[0]];
node.symbol.parent = symbol;
links.resolvedType = createObjectType(TypeFlags.Anonymous, symbol);
}
return links.resolvedType;
}
function getTypeFromTypeLiteralNode(node: TypeLiteralNode): Type {
var links = getNodeLinks(node);
if (!links.resolvedType) {
@ -3011,6 +3028,9 @@ module ts {
return getTypeFromUnionTypeNode(<UnionTypeNode>node);
case SyntaxKind.ParenType:
return getTypeFromTypeNode((<ParenTypeNode>node).type);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
return getTypefromFunctionOrConstructorTypeNode(<SignatureDeclaration>node);
case SyntaxKind.TypeLiteral:
return getTypeFromTypeLiteralNode(<TypeLiteralNode>node);
// This function assumes that an identifier or qualified name is a type expression
@ -5858,7 +5878,7 @@ module ts {
}
if (node.kind === SyntaxKind.NewExpression) {
var declaration = signature.declaration;
if (declaration && (declaration.kind !== SyntaxKind.Constructor && declaration.kind !== SyntaxKind.ConstructSignature)) {
if (declaration && (declaration.kind !== SyntaxKind.Constructor && declaration.kind !== SyntaxKind.ConstructSignature && declaration.kind !== SyntaxKind.ConstructorType)) {
// When resolved signature is a call signature (and not a construct signature) the result type is any
if (compilerOptions.noImplicitAny) {
error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
@ -8275,6 +8295,8 @@ module ts {
return checkParameter(<ParameterDeclaration>node);
case SyntaxKind.Property:
return checkPropertyDeclaration(<PropertyDeclaration>node);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
@ -9047,7 +9069,9 @@ module ts {
function writeTypeAtLocation(location: Node, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
// Get type of the symbol if this is the valid symbol otherwise get type at location
var symbol = getSymbolOfNode(location);
var type = symbol && !(symbol.flags & SymbolFlags.TypeLiteral) ? getTypeOfSymbol(symbol) : getTypeFromTypeNode(location);
var type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.CallSignature | SymbolFlags.ConstructSignature))
? getTypeOfSymbol(symbol)
: getTypeFromTypeNode(location);
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
}

View file

@ -205,6 +205,8 @@ module ts {
return child((<PropertyDeclaration>node).name) ||
child((<PropertyDeclaration>node).type) ||
child((<PropertyDeclaration>node).initializer);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
@ -1882,16 +1884,16 @@ module ts {
return finishNode(node);
}
function parseFunctionType(signatureKind: SyntaxKind): TypeLiteralNode {
var node = <TypeLiteralNode>createNode(SyntaxKind.TypeLiteral);
var member = <SignatureDeclaration>createNode(signatureKind);
var sig = parseSignature(signatureKind, SyntaxKind.EqualsGreaterThanToken, /* returnTokenRequired */ true);
function parseFunctionType(typeKind: SyntaxKind): SignatureDeclaration {
var member = <SignatureDeclaration>createNode(typeKind);
var sig = parseSignature(typeKind === SyntaxKind.FunctionType ? SyntaxKind.CallSignature : SyntaxKind.ConstructSignature,
SyntaxKind.EqualsGreaterThanToken, /* returnTokenRequired */ true);
member.typeParameters = sig.typeParameters;
member.parameters = sig.parameters;
member.type = sig.type;
finishNode(member);
node.members = createNodeArray(member);
return finishNode(node);
return member;
}
function parseKeywordAndNoDot(): Node {
@ -2011,10 +2013,10 @@ module ts {
function parseType(): TypeNode {
if (isStartOfFunctionType()) {
return parseFunctionType(SyntaxKind.CallSignature);
return parseFunctionType(SyntaxKind.FunctionType);
}
if (token === SyntaxKind.NewKeyword) {
return parseFunctionType(SyntaxKind.ConstructSignature);
return parseFunctionType(SyntaxKind.ConstructorType);
}
return parseUnionType();
}

View file

@ -155,6 +155,8 @@ module ts {
IndexSignature,
// Type
TypeReference,
FunctionType,
ConstructorType,
TypeQuery,
TypeLiteral,
ArrayType,
@ -1357,4 +1359,4 @@ module ts {
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
}
}
}