@@ -100,11 +100,18 @@ module ts {
100100 let globalIterableType: ObjectType;
101101
102102 let anyArrayType: Type;
103+ let globalTypedPropertyDescriptorType: ObjectType;
104+ let globalClassDecoratorType: ObjectType;
105+ let globalClassAnnotationType: ObjectType;
106+ let globalParameterAnnotationType: ObjectType;
107+ let globalPropertyAnnotationType: ObjectType;
108+ let globalPropertyDecoratorType: ObjectType;
103109
104110 let tupleTypes: Map<TupleType> = {};
105111 let unionTypes: Map<UnionType> = {};
106112 let stringLiteralTypes: Map<StringLiteralType> = {};
107113 let emitExtends = false;
114+ let emitDecorate = false;
108115
109116 let mergedSymbols: Symbol[] = [];
110117 let symbolLinks: SymbolLinks[] = [];
@@ -311,6 +318,7 @@ module ts {
311318 let lastLocation: Node;
312319 let propertyWithInvalidInitializer: Node;
313320 let errorLocation = location;
321+ let grandparent: Node;
314322
315323 loop: while (location) {
316324 // Locals of a source file are not in scope (because they get merged into the global symbol table)
@@ -376,7 +384,7 @@ module ts {
376384 // }
377385 //
378386 case SyntaxKind.ComputedPropertyName:
379- let grandparent = location.parent.parent;
387+ grandparent = location.parent.parent;
380388 if (grandparent.kind === SyntaxKind.ClassDeclaration || grandparent.kind === SyntaxKind.InterfaceDeclaration) {
381389 // A reference to this grandparent's type parameters would be an error
382390 if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & SymbolFlags.Type)) {
@@ -408,6 +416,26 @@ module ts {
408416 break loop;
409417 }
410418 break;
419+ case SyntaxKind.Decorator:
420+ if (location.parent) {
421+ lastLocation = location;
422+ grandparent = location.parent.parent;
423+ if (location.parent.kind === SyntaxKind.Parameter) {
424+ // Parameter decorators are resolved in the context of their great-grandparent
425+ if (grandparent) {
426+ location = grandparent.parent;
427+ }
428+ else {
429+ break loop;
430+ }
431+ }
432+ else {
433+ // all other decorators are resolved in the context of their grandparent
434+ location = grandparent;
435+ }
436+ continue;
437+ }
438+ break;
411439 }
412440 lastLocation = location;
413441 location = location.parent;
@@ -7852,7 +7880,7 @@ module ts {
78527880 // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
78537881
78547882 // Grammar checking
7855- checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
7883+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
78567884
78577885 checkVariableLikeDeclaration(node);
78587886 let func = getContainingFunction(node);
@@ -7954,7 +7982,7 @@ module ts {
79547982
79557983 function checkPropertyDeclaration(node: PropertyDeclaration) {
79567984 // Grammar checking
7957- checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
7985+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
79587986
79597987 checkVariableLikeDeclaration(node);
79607988 }
@@ -8093,6 +8121,10 @@ module ts {
80938121 checkFunctionLikeDeclaration(node);
80948122 }
80958123
8124+ function checkIncompleteDeclaration(node: Declaration) {
8125+ error(node, Diagnostics.Declaration_expected);
8126+ }
8127+
80968128 function checkTypeReference(node: TypeReferenceNode) {
80978129 // Grammar checking
80988130 checkGrammarTypeArguments(node, node.typeArguments);
@@ -8484,6 +8516,70 @@ module ts {
84848516 }
84858517 }
84868518
8519+ function checkDecoratorSignature(node: Decorator, exprType: Type, expectedAnnotationType: Type, parentType?: Type, expectedDecoratorType?: Type, message?: DiagnosticMessage) {
8520+ if (checkTypeAssignableTo(exprType, expectedAnnotationType, node) && expectedDecoratorType) {
8521+ let signature = getSingleCallSignature(expectedDecoratorType);
8522+ if (!signature) {
8523+ // 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
8524+ // and we have already reported an error in initializeTypeChecker.
8525+ return;
8526+ }
8527+
8528+ let instantiatedSignature = getSignatureInstantiation(signature, [parentType]);
8529+ let instantiatedSignatureType = getOrCreateTypeFromSignature(instantiatedSignature);
8530+ checkTypeAssignableTo(exprType, instantiatedSignatureType, node, message);
8531+ }
8532+ }
8533+
8534+ /** Check a decorator */
8535+ function checkDecorator(node: Decorator): void {
8536+ let expression: Expression = node.expression;
8537+ let exprType = checkExpression(expression);
8538+
8539+ switch (node.parent.kind) {
8540+ case SyntaxKind.ClassDeclaration:
8541+ let classSymbol = getSymbolOfNode(node.parent);
8542+ let classType = getTypeOfSymbol(classSymbol);
8543+ checkDecoratorSignature(node, exprType, globalClassAnnotationType, classType, globalClassDecoratorType, Diagnostics.Decorators_may_not_change_the_type_of_a_class);
8544+ break;
8545+
8546+ case SyntaxKind.PropertyDeclaration:
8547+ case SyntaxKind.MethodDeclaration:
8548+ case SyntaxKind.GetAccessor:
8549+ case SyntaxKind.SetAccessor:
8550+ let propertyType = getTypeOfNode(node.parent);
8551+ checkDecoratorSignature(node, exprType, globalPropertyAnnotationType, propertyType, globalPropertyDecoratorType, Diagnostics.Decorators_may_not_change_the_type_of_a_member);
8552+ break;
8553+
8554+ case SyntaxKind.Parameter:
8555+ checkDecoratorSignature(node, exprType, globalParameterAnnotationType);
8556+ break;
8557+ }
8558+ }
8559+
8560+ /** Check the decorators of a node */
8561+ function checkDecorators(node: Node): void {
8562+ if (!node.decorators) {
8563+ return;
8564+ }
8565+
8566+ switch (node.kind) {
8567+ case SyntaxKind.ClassDeclaration:
8568+ case SyntaxKind.MethodDeclaration:
8569+ case SyntaxKind.GetAccessor:
8570+ case SyntaxKind.SetAccessor:
8571+ case SyntaxKind.PropertyDeclaration:
8572+ case SyntaxKind.Parameter:
8573+ emitDecorate = true;
8574+ break;
8575+
8576+ default:
8577+ return;
8578+ }
8579+
8580+ forEach(node.decorators, checkDecorator);
8581+ }
8582+
84878583 function checkFunctionDeclaration(node: FunctionDeclaration): void {
84888584 if (produceDiagnostics) {
84898585 checkFunctionLikeDeclaration(node) ||
@@ -8498,6 +8594,7 @@ module ts {
84988594 }
84998595
85008596 function checkFunctionLikeDeclaration(node: FunctionLikeDeclaration): void {
8597+ checkDecorators(node);
85018598 checkSignatureDeclaration(node);
85028599
85038600 // Do not use hasDynamicName here, because that returns false for well known symbols.
@@ -8780,6 +8877,7 @@ module ts {
87808877
87818878 // Check variable, parameter, or property declaration
87828879 function checkVariableLikeDeclaration(node: VariableLikeDeclaration) {
8880+ checkDecorators(node);
87838881 checkSourceElement(node.type);
87848882 // For a computed property, just check the initializer and exit
87858883 // Do not use hasDynamicName here, because that returns false for well known symbols.
@@ -8852,7 +8950,7 @@ module ts {
88528950
88538951 function checkVariableStatement(node: VariableStatement) {
88548952 // Grammar checking
8855- checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node);
8953+ checkGrammarDecorators(node) || checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node);
88568954
88578955 forEach(node.declarationList.declarations, checkSourceElement);
88588956 }
@@ -9483,7 +9581,7 @@ module ts {
94839581 function checkClassDeclaration(node: ClassDeclaration) {
94849582 // Grammar checking
94859583 checkGrammarClassDeclarationHeritageClauses(node);
9486-
9584+ checkDecorators(node);
94879585 if (node.name) {
94889586 checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
94899587 checkCollisionWithCapturedThisVariable(node, node.name);
@@ -9688,7 +9786,7 @@ module ts {
96889786
96899787 function checkInterfaceDeclaration(node: InterfaceDeclaration) {
96909788 // Grammar checking
9691- checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
9789+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
96929790
96939791 checkTypeParameters(node.typeParameters);
96949792 if (produceDiagnostics) {
@@ -9725,7 +9823,7 @@ module ts {
97259823
97269824 function checkTypeAliasDeclaration(node: TypeAliasDeclaration) {
97279825 // Grammar checking
9728- checkGrammarModifiers(node);
9826+ checkGrammarDecorators(node) || checkGrammarModifiers(node);
97299827
97309828 checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0);
97319829 checkSourceElement(node.type);
@@ -9894,7 +9992,7 @@ module ts {
98949992 }
98959993
98969994 // Grammar checking
9897- checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node);
9995+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node);
98989996
98999997 checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
99009998 checkCollisionWithCapturedThisVariable(node, node.name);
@@ -9960,7 +10058,7 @@ module ts {
996010058 function checkModuleDeclaration(node: ModuleDeclaration) {
996110059 if (produceDiagnostics) {
996210060 // Grammar checking
9963- if (!checkGrammarModifiers(node)) {
10061+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node)) {
996410062 if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) {
996510063 grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names);
996610064 }
@@ -10055,7 +10153,7 @@ module ts {
1005510153 }
1005610154
1005710155 function checkImportDeclaration(node: ImportDeclaration) {
10058- if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10156+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
1005910157 grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers);
1006010158 }
1006110159 if (checkExternalImportOrExportDeclaration(node)) {
@@ -10077,7 +10175,7 @@ module ts {
1007710175 }
1007810176
1007910177 function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) {
10080- checkGrammarModifiers(node);
10178+ checkGrammarDecorators(node) || checkGrammarModifiers(node);
1008110179 if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
1008210180 checkImportBinding(node);
1008310181 if (node.flags & NodeFlags.Export) {
@@ -10108,7 +10206,7 @@ module ts {
1010810206 }
1010910207
1011010208 function checkExportDeclaration(node: ExportDeclaration) {
10111- if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10209+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
1011210210 grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers);
1011310211 }
1011410212 if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
@@ -10132,7 +10230,7 @@ module ts {
1013210230 return;
1013310231 }
1013410232 // Grammar checking
10135- if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10233+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
1013610234 grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
1013710235 }
1013810236 if (node.expression) {
@@ -10232,6 +10330,8 @@ module ts {
1023210330 case SyntaxKind.GetAccessor:
1023310331 case SyntaxKind.SetAccessor:
1023410332 return checkAccessorDeclaration(<AccessorDeclaration>node);
10333+ case SyntaxKind.IncompleteDeclaration:
10334+ return checkIncompleteDeclaration(<Declaration>node);
1023510335 case SyntaxKind.TypeReference:
1023610336 return checkTypeReference(<TypeReferenceNode>node);
1023710337 case SyntaxKind.TypeQuery:
@@ -10436,6 +10536,10 @@ module ts {
1043610536 links.flags |= NodeCheckFlags.EmitExtends;
1043710537 }
1043810538
10539+ if (emitDecorate) {
10540+ links.flags |= NodeCheckFlags.EmitDecorate;
10541+ }
10542+
1043910543 links.flags |= NodeCheckFlags.TypeChecked;
1044010544 }
1044110545 }
@@ -11235,6 +11339,12 @@ module ts {
1123511339 globalNumberType = getGlobalType("Number");
1123611340 globalBooleanType = getGlobalType("Boolean");
1123711341 globalRegExpType = getGlobalType("RegExp");
11342+ globalTypedPropertyDescriptorType = getTypeOfGlobalSymbol(getGlobalTypeSymbol("TypedPropertyDescriptor"), 1);
11343+ globalClassDecoratorType = getGlobalType("ClassDecorator");
11344+ globalPropertyDecoratorType = getGlobalType("PropertyDecorator");
11345+ globalClassAnnotationType = getGlobalType("ClassAnnotation");
11346+ globalPropertyAnnotationType = getGlobalType("PropertyAnnotation");
11347+ globalParameterAnnotationType = getGlobalType("ParameterAnnotation");
1123811348
1123911349 // If we're in ES6 mode, load the TemplateStringsArray.
1124011350 // Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios.
@@ -11259,6 +11369,42 @@ module ts {
1125911369
1126011370
1126111371 // GRAMMAR CHECKING
11372+ function checkGrammarDecorators(node: Node): boolean {
11373+ if (!node.decorators) {
11374+ return false;
11375+ }
11376+
11377+ let target = node;
11378+ while (target) {
11379+ switch (target.kind) {
11380+ case SyntaxKind.ClassDeclaration:
11381+ return false;
11382+
11383+ case SyntaxKind.Constructor:
11384+ if (node.kind !== SyntaxKind.Parameter) {
11385+ break;
11386+ }
11387+
11388+ case SyntaxKind.PropertyDeclaration:
11389+ case SyntaxKind.Parameter:
11390+ target = target.parent;
11391+ continue;
11392+
11393+
11394+ case SyntaxKind.MethodDeclaration:
11395+ case SyntaxKind.GetAccessor:
11396+ case SyntaxKind.SetAccessor:
11397+ if ((<FunctionLikeDeclaration>target).body) {
11398+ target = target.parent;
11399+ continue;
11400+ }
11401+ break;
11402+ }
11403+ break;
11404+ }
11405+ return grammarErrorOnNode(node, Diagnostics.Decorators_are_not_valid_on_this_declaration_type);
11406+ }
11407+
1126211408 function checkGrammarModifiers(node: Node): boolean {
1126311409 switch (node.kind) {
1126411410 case SyntaxKind.GetAccessor:
@@ -11455,7 +11601,7 @@ module ts {
1145511601 function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
1145611602 // Prevent cascading error by short-circuit
1145711603 let file = getSourceFileOfNode(node);
11458- return checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) ||
11604+ return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) ||
1145911605 checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
1146011606 }
1146111607
@@ -11512,7 +11658,7 @@ module ts {
1151211658
1151311659 function checkGrammarIndexSignature(node: SignatureDeclaration) {
1151411660 // Prevent cascading error by short-circuit
11515- checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node) || checkGrammarForIndexSignatureModifier(node);
11661+ return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node) || checkGrammarForIndexSignatureModifier(node);
1151611662 }
1151711663
1151811664 function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray<TypeNode>): boolean {
@@ -11561,7 +11707,7 @@ module ts {
1156111707 let seenExtendsClause = false;
1156211708 let seenImplementsClause = false;
1156311709
11564- if (!checkGrammarModifiers(node) && node.heritageClauses) {
11710+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && node.heritageClauses) {
1156511711 for (let heritageClause of node.heritageClauses) {
1156611712 if (heritageClause.token === SyntaxKind.ExtendsKeyword) {
1156711713 if (seenExtendsClause) {
0 commit comments