-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,11 +100,18 @@ module ts { | |
let globalIterableType: ObjectType; | ||
|
||
let anyArrayType: Type; | ||
let globalTypedPropertyDescriptorType: ObjectType; | ||
let globalClassDecoratorType: ObjectType; | ||
let globalClassAnnotationType: ObjectType; | ||
let globalParameterAnnotationType: ObjectType; | ||
let globalPropertyAnnotationType: ObjectType; | ||
let globalPropertyDecoratorType: ObjectType; | ||
|
||
let tupleTypes: Map<TupleType> = {}; | ||
let unionTypes: Map<UnionType> = {}; | ||
let stringLiteralTypes: Map<StringLiteralType> = {}; | ||
let emitExtends = false; | ||
let emitDecorate = false; | ||
|
||
let mergedSymbols: Symbol[] = []; | ||
let symbolLinks: SymbolLinks[] = []; | ||
|
@@ -311,6 +318,7 @@ module ts { | |
let lastLocation: Node; | ||
let propertyWithInvalidInitializer: Node; | ||
let errorLocation = location; | ||
let grandparent: Node; | ||
|
||
loop: while (location) { | ||
// Locals of a source file are not in scope (because they get merged into the global symbol table) | ||
|
@@ -376,7 +384,7 @@ module ts { | |
// } | ||
// | ||
case SyntaxKind.ComputedPropertyName: | ||
let grandparent = location.parent.parent; | ||
grandparent = location.parent.parent; | ||
if (grandparent.kind === SyntaxKind.ClassDeclaration || grandparent.kind === SyntaxKind.InterfaceDeclaration) { | ||
// A reference to this grandparent's type parameters would be an error | ||
if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & SymbolFlags.Type)) { | ||
|
@@ -408,6 +416,26 @@ module ts { | |
break loop; | ||
} | ||
break; | ||
case SyntaxKind.Decorator: | ||
if (location.parent) { | ||
lastLocation = location; | ||
grandparent = location.parent.parent; | ||
if (location.parent.kind === SyntaxKind.Parameter) { | ||
// Parameter decorators are resolved in the context of their great-grandparent | ||
if (grandparent) { | ||
location = grandparent.parent; | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
else { | ||
break loop; | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
} | ||
else { | ||
// all other decorators are resolved in the context of their grandparent | ||
location = grandparent; | ||
} | ||
continue; | ||
} | ||
break; | ||
} | ||
lastLocation = location; | ||
location = location.parent; | ||
|
@@ -7852,7 +7880,7 @@ module ts { | |
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1) | ||
|
||
// Grammar checking | ||
checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name); | ||
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name); | ||
|
||
checkVariableLikeDeclaration(node); | ||
let func = getContainingFunction(node); | ||
|
@@ -7954,7 +7982,7 @@ module ts { | |
|
||
function checkPropertyDeclaration(node: PropertyDeclaration) { | ||
// Grammar checking | ||
checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name); | ||
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name); | ||
|
||
checkVariableLikeDeclaration(node); | ||
} | ||
|
@@ -8093,6 +8121,10 @@ module ts { | |
checkFunctionLikeDeclaration(node); | ||
} | ||
|
||
function checkIncompleteDeclaration(node: Declaration) { | ||
error(node, Diagnostics.Declaration_expected); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
|
||
function checkTypeReference(node: TypeReferenceNode) { | ||
// Grammar checking | ||
checkGrammarTypeArguments(node, node.typeArguments); | ||
|
@@ -8484,6 +8516,70 @@ module ts { | |
} | ||
} | ||
|
||
function checkDecoratorSignature(node: Decorator, exprType: Type, expectedAnnotationType: Type, parentType?: Type, expectedDecoratorType?: Type, message?: DiagnosticMessage) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
Contributor
|
||
if (checkTypeAssignableTo(exprType, expectedAnnotationType, node) && expectedDecoratorType) { | ||
let signature = getSingleCallSignature(expectedDecoratorType); | ||
if (!signature) { | ||
// if we couldn't get the signature of the decorator function type, it is likely because we are using an out-of-date lib.d.ts | ||
// and we have already reported an error in initializeTypeChecker. | ||
return; | ||
} | ||
|
||
let instantiatedSignature = getSignatureInstantiation(signature, [parentType]); | ||
let instantiatedSignatureType = getOrCreateTypeFromSignature(instantiatedSignature); | ||
checkTypeAssignableTo(exprType, instantiatedSignatureType, node, message); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
Contributor
|
||
} | ||
} | ||
|
||
/** Check a decorator */ | ||
function checkDecorator(node: Decorator): void { | ||
let expression: Expression = node.expression; | ||
let exprType = checkExpression(expression); | ||
|
||
switch (node.parent.kind) { | ||
case SyntaxKind.ClassDeclaration: | ||
let classSymbol = getSymbolOfNode(node.parent); | ||
let classType = getTypeOfSymbol(classSymbol); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
checkDecoratorSignature(node, exprType, globalClassAnnotationType, classType, globalClassDecoratorType, Diagnostics.Decorators_may_not_change_the_type_of_a_class); | ||
break; | ||
|
||
case SyntaxKind.PropertyDeclaration: | ||
case SyntaxKind.MethodDeclaration: | ||
case SyntaxKind.GetAccessor: | ||
case SyntaxKind.SetAccessor: | ||
let propertyType = getTypeOfNode(node.parent); | ||
checkDecoratorSignature(node, exprType, globalPropertyAnnotationType, propertyType, globalPropertyDecoratorType, Diagnostics.Decorators_may_not_change_the_type_of_a_member); | ||
break; | ||
|
||
case SyntaxKind.Parameter: | ||
checkDecoratorSignature(node, exprType, globalParameterAnnotationType); | ||
break; | ||
} | ||
} | ||
|
||
/** Check the decorators of a node */ | ||
function checkDecorators(node: Node): void { | ||
if (!node.decorators) { | ||
return; | ||
} | ||
|
||
switch (node.kind) { | ||
case SyntaxKind.ClassDeclaration: | ||
case SyntaxKind.MethodDeclaration: | ||
case SyntaxKind.GetAccessor: | ||
case SyntaxKind.SetAccessor: | ||
case SyntaxKind.PropertyDeclaration: | ||
case SyntaxKind.Parameter: | ||
emitDecorate = true; | ||
break; | ||
|
||
default: | ||
return; | ||
} | ||
|
||
forEach(node.decorators, checkDecorator); | ||
} | ||
|
||
function checkFunctionDeclaration(node: FunctionDeclaration): void { | ||
if (produceDiagnostics) { | ||
checkFunctionLikeDeclaration(node) || | ||
|
@@ -8498,6 +8594,7 @@ module ts { | |
} | ||
|
||
function checkFunctionLikeDeclaration(node: FunctionLikeDeclaration): void { | ||
checkDecorators(node); | ||
checkSignatureDeclaration(node); | ||
|
||
// Do not use hasDynamicName here, because that returns false for well known symbols. | ||
|
@@ -8780,6 +8877,7 @@ module ts { | |
|
||
// Check variable, parameter, or property declaration | ||
function checkVariableLikeDeclaration(node: VariableLikeDeclaration) { | ||
checkDecorators(node); | ||
checkSourceElement(node.type); | ||
// For a computed property, just check the initializer and exit | ||
// Do not use hasDynamicName here, because that returns false for well known symbols. | ||
|
@@ -8852,7 +8950,7 @@ module ts { | |
|
||
function checkVariableStatement(node: VariableStatement) { | ||
// Grammar checking | ||
checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); | ||
checkGrammarDecorators(node) || checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); | ||
|
||
forEach(node.declarationList.declarations, checkSourceElement); | ||
} | ||
|
@@ -9483,7 +9581,7 @@ module ts { | |
function checkClassDeclaration(node: ClassDeclaration) { | ||
// Grammar checking | ||
checkGrammarClassDeclarationHeritageClauses(node); | ||
|
||
checkDecorators(node); | ||
if (node.name) { | ||
checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0); | ||
checkCollisionWithCapturedThisVariable(node, node.name); | ||
|
@@ -9688,7 +9786,7 @@ module ts { | |
|
||
function checkInterfaceDeclaration(node: InterfaceDeclaration) { | ||
// Grammar checking | ||
checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node); | ||
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node); | ||
|
||
checkTypeParameters(node.typeParameters); | ||
if (produceDiagnostics) { | ||
|
@@ -9725,7 +9823,7 @@ module ts { | |
|
||
function checkTypeAliasDeclaration(node: TypeAliasDeclaration) { | ||
// Grammar checking | ||
checkGrammarModifiers(node); | ||
checkGrammarDecorators(node) || checkGrammarModifiers(node); | ||
|
||
checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0); | ||
checkSourceElement(node.type); | ||
|
@@ -9894,7 +9992,7 @@ module ts { | |
} | ||
|
||
// Grammar checking | ||
checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node); | ||
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node); | ||
|
||
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0); | ||
checkCollisionWithCapturedThisVariable(node, node.name); | ||
|
@@ -9960,7 +10058,7 @@ module ts { | |
function checkModuleDeclaration(node: ModuleDeclaration) { | ||
if (produceDiagnostics) { | ||
// Grammar checking | ||
if (!checkGrammarModifiers(node)) { | ||
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node)) { | ||
if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) { | ||
grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names); | ||
} | ||
|
@@ -10055,7 +10153,7 @@ module ts { | |
} | ||
|
||
function checkImportDeclaration(node: ImportDeclaration) { | ||
if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { | ||
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { | ||
grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); | ||
} | ||
if (checkExternalImportOrExportDeclaration(node)) { | ||
|
@@ -10077,7 +10175,7 @@ module ts { | |
} | ||
|
||
function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) { | ||
checkGrammarModifiers(node); | ||
checkGrammarDecorators(node) || checkGrammarModifiers(node); | ||
if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { | ||
checkImportBinding(node); | ||
if (node.flags & NodeFlags.Export) { | ||
|
@@ -10108,7 +10206,7 @@ module ts { | |
} | ||
|
||
function checkExportDeclaration(node: ExportDeclaration) { | ||
if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { | ||
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { | ||
grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); | ||
} | ||
if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { | ||
|
@@ -10132,7 +10230,7 @@ module ts { | |
return; | ||
} | ||
// Grammar checking | ||
if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { | ||
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { | ||
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers); | ||
} | ||
if (node.expression) { | ||
|
@@ -10232,6 +10330,8 @@ module ts { | |
case SyntaxKind.GetAccessor: | ||
case SyntaxKind.SetAccessor: | ||
return checkAccessorDeclaration(<AccessorDeclaration>node); | ||
case SyntaxKind.IncompleteDeclaration: | ||
return checkIncompleteDeclaration(<Declaration>node); | ||
case SyntaxKind.TypeReference: | ||
return checkTypeReference(<TypeReferenceNode>node); | ||
case SyntaxKind.TypeQuery: | ||
|
@@ -10436,6 +10536,10 @@ module ts { | |
links.flags |= NodeCheckFlags.EmitExtends; | ||
} | ||
|
||
if (emitDecorate) { | ||
links.flags |= NodeCheckFlags.EmitDecorate; | ||
} | ||
|
||
links.flags |= NodeCheckFlags.TypeChecked; | ||
} | ||
} | ||
|
@@ -11235,6 +11339,12 @@ module ts { | |
globalNumberType = getGlobalType("Number"); | ||
globalBooleanType = getGlobalType("Boolean"); | ||
globalRegExpType = getGlobalType("RegExp"); | ||
globalTypedPropertyDescriptorType = getTypeOfGlobalSymbol(getGlobalTypeSymbol("TypedPropertyDescriptor"), 1); | ||
globalClassDecoratorType = getGlobalType("ClassDecorator"); | ||
globalPropertyDecoratorType = getGlobalType("PropertyDecorator"); | ||
globalClassAnnotationType = getGlobalType("ClassAnnotation"); | ||
globalPropertyAnnotationType = getGlobalType("PropertyAnnotation"); | ||
globalParameterAnnotationType = getGlobalType("ParameterAnnotation"); | ||
|
||
// If we're in ES6 mode, load the TemplateStringsArray. | ||
// Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios. | ||
|
@@ -11259,6 +11369,42 @@ module ts { | |
|
||
|
||
// GRAMMAR CHECKING | ||
function checkGrammarDecorators(node: Node): boolean { | ||
if (!node.decorators) { | ||
return false; | ||
} | ||
|
||
let target = node; | ||
while (target) { | ||
switch (target.kind) { | ||
case SyntaxKind.ClassDeclaration: | ||
return false; | ||
|
||
case SyntaxKind.Constructor: | ||
if (node.kind !== SyntaxKind.Parameter) { | ||
break; | ||
} | ||
|
||
case SyntaxKind.PropertyDeclaration: | ||
case SyntaxKind.Parameter: | ||
target = target.parent; | ||
continue; | ||
|
||
|
||
case SyntaxKind.MethodDeclaration: | ||
case SyntaxKind.GetAccessor: | ||
case SyntaxKind.SetAccessor: | ||
if ((<FunctionLikeDeclaration>target).body) { | ||
target = target.parent; | ||
continue; | ||
} | ||
break; | ||
} | ||
break; | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
Contributor
|
||
return grammarErrorOnNode(node, Diagnostics.Decorators_are_not_valid_on_this_declaration_type); | ||
} | ||
|
||
function checkGrammarModifiers(node: Node): boolean { | ||
switch (node.kind) { | ||
case SyntaxKind.GetAccessor: | ||
|
@@ -11455,7 +11601,7 @@ module ts { | |
function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean { | ||
// Prevent cascading error by short-circuit | ||
let file = getSourceFileOfNode(node); | ||
return checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) || | ||
return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) || | ||
checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file); | ||
} | ||
|
||
|
@@ -11512,7 +11658,7 @@ module ts { | |
|
||
function checkGrammarIndexSignature(node: SignatureDeclaration) { | ||
// Prevent cascading error by short-circuit | ||
checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node) || checkGrammarForIndexSignatureModifier(node); | ||
return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node) || checkGrammarForIndexSignatureModifier(node); | ||
} | ||
|
||
function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray<TypeNode>): boolean { | ||
|
@@ -11561,7 +11707,7 @@ module ts { | |
let seenExtendsClause = false; | ||
let seenImplementsClause = false; | ||
|
||
if (!checkGrammarModifiers(node) && node.heritageClauses) { | ||
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && node.heritageClauses) { | ||
for (let heritageClause of node.heritageClauses) { | ||
if (heritageClause.token === SyntaxKind.ExtendsKeyword) { | ||
if (seenExtendsClause) { | ||
|
Seems like this is only correct for method and constructor parameters, but what about function parameters?