Function and constructor types in the syntax tree.
This commit is contained in:
parent
bdfb5697af
commit
d948510425
4 changed files with 64 additions and 16 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -155,6 +155,8 @@ module ts {
|
|||
IndexSignature,
|
||||
// Type
|
||||
TypeReference,
|
||||
FunctionType,
|
||||
ConstructorType,
|
||||
TypeQuery,
|
||||
TypeLiteral,
|
||||
ArrayType,
|
||||
|
|
Loading…
Reference in a new issue