Merge pull request #1169 from Microsoft/functionConstructorNodes
Function and constructor types in the syntax tree.
This commit is contained in:
commit
20599e6fe8
|
@ -93,10 +93,16 @@ module ts {
|
|||
return (<Identifier>node.name).text;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor: return "__constructor";
|
||||
case SyntaxKind.CallSignature: return "__call";
|
||||
case SyntaxKind.ConstructSignature: return "__new";
|
||||
case SyntaxKind.IndexSignature: return "__index";
|
||||
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 +120,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 +242,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 +305,25 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
function bindFunctionOrConstructorType(node: SignatureDeclaration) {
|
||||
// For a given function symbol "<...>(...) => T" we want to generate a symbol identical
|
||||
// to the one we would get for: { <...>(...): T }
|
||||
//
|
||||
// We do that by making an anonymous type literal symbol, and then setting the function
|
||||
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
|
||||
// from an actual type literal symbol you would have gotten had you used the long form.
|
||||
|
||||
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);
|
||||
|
||||
var typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
|
||||
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
|
||||
typeLiteralSymbol.members = {};
|
||||
typeLiteralSymbol.members[node.kind === SyntaxKind.FunctionType ? "__call" : "__new"] = symbol
|
||||
}
|
||||
|
||||
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) {
|
||||
var symbol = createSymbol(symbolKind, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolKind);
|
||||
|
@ -358,12 +388,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 +409,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:
|
||||
|
@ -2960,8 +2962,8 @@ module ts {
|
|||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromTypeLiteralNode(node: TypeLiteralNode): Type {
|
||||
|
||||
function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node): Type {
|
||||
var links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
// Deferred resolution of members is handled by resolveObjectTypeMembers
|
||||
|
@ -3011,8 +3013,10 @@ module ts {
|
|||
return getTypeFromUnionTypeNode(<UnionTypeNode>node);
|
||||
case SyntaxKind.ParenType:
|
||||
return getTypeFromTypeNode((<ParenTypeNode>node).type);
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
return getTypeFromTypeLiteralNode(<TypeLiteralNode>node);
|
||||
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
||||
// This function assumes that an identifier or qualified name is a type expression
|
||||
// Callers should first ensure this by calling isTypeNode
|
||||
case SyntaxKind.Identifier:
|
||||
|
@ -5858,7 +5862,11 @@ 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);
|
||||
|
@ -6801,7 +6809,7 @@ module ts {
|
|||
function checkTypeLiteral(node: TypeLiteralNode) {
|
||||
forEach(node.members, checkSourceElement);
|
||||
if (fullTypeCheck) {
|
||||
var type = getTypeFromTypeLiteralNode(node);
|
||||
var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
||||
checkIndexConstraints(type);
|
||||
checkTypeForDuplicateIndexSignatures(node);
|
||||
}
|
||||
|
@ -8275,6 +8283,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 +9057,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,
|
||||
|
@ -1357,4 +1359,4 @@ module ts {
|
|||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue