@@ -100,11 +100,18 @@ module ts {
100
100
let globalIterableType: ObjectType;
101
101
102
102
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;
103
109
104
110
let tupleTypes: Map<TupleType> = {};
105
111
let unionTypes: Map<UnionType> = {};
106
112
let stringLiteralTypes: Map<StringLiteralType> = {};
107
113
let emitExtends = false;
114
+ let emitDecorate = false;
108
115
109
116
let mergedSymbols: Symbol[] = [];
110
117
let symbolLinks: SymbolLinks[] = [];
@@ -311,6 +318,7 @@ module ts {
311
318
let lastLocation: Node;
312
319
let propertyWithInvalidInitializer: Node;
313
320
let errorLocation = location;
321
+ let grandparent: Node;
314
322
315
323
loop: while (location) {
316
324
// Locals of a source file are not in scope (because they get merged into the global symbol table)
@@ -376,7 +384,7 @@ module ts {
376
384
// }
377
385
//
378
386
case SyntaxKind.ComputedPropertyName:
379
- let grandparent = location.parent.parent;
387
+ grandparent = location.parent.parent;
380
388
if (grandparent.kind === SyntaxKind.ClassDeclaration || grandparent.kind === SyntaxKind.InterfaceDeclaration) {
381
389
// A reference to this grandparent's type parameters would be an error
382
390
if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & SymbolFlags.Type)) {
@@ -408,6 +416,26 @@ module ts {
408
416
break loop;
409
417
}
410
418
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;
411
439
}
412
440
lastLocation = location;
413
441
location = location.parent;
@@ -7852,7 +7880,7 @@ module ts {
7852
7880
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
7853
7881
7854
7882
// Grammar checking
7855
- checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
7883
+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
7856
7884
7857
7885
checkVariableLikeDeclaration(node);
7858
7886
let func = getContainingFunction(node);
@@ -7954,7 +7982,7 @@ module ts {
7954
7982
7955
7983
function checkPropertyDeclaration(node: PropertyDeclaration) {
7956
7984
// Grammar checking
7957
- checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
7985
+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
7958
7986
7959
7987
checkVariableLikeDeclaration(node);
7960
7988
}
@@ -8093,6 +8121,10 @@ module ts {
8093
8121
checkFunctionLikeDeclaration(node);
8094
8122
}
8095
8123
8124
+ function checkIncompleteDeclaration(node: Declaration) {
8125
+ error(node, Diagnostics.Declaration_expected);
8126
+ }
8127
+
8096
8128
function checkTypeReference(node: TypeReferenceNode) {
8097
8129
// Grammar checking
8098
8130
checkGrammarTypeArguments(node, node.typeArguments);
@@ -8484,6 +8516,70 @@ module ts {
8484
8516
}
8485
8517
}
8486
8518
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
+
8487
8583
function checkFunctionDeclaration(node: FunctionDeclaration): void {
8488
8584
if (produceDiagnostics) {
8489
8585
checkFunctionLikeDeclaration(node) ||
@@ -8498,6 +8594,7 @@ module ts {
8498
8594
}
8499
8595
8500
8596
function checkFunctionLikeDeclaration(node: FunctionLikeDeclaration): void {
8597
+ checkDecorators(node);
8501
8598
checkSignatureDeclaration(node);
8502
8599
8503
8600
// Do not use hasDynamicName here, because that returns false for well known symbols.
@@ -8780,6 +8877,7 @@ module ts {
8780
8877
8781
8878
// Check variable, parameter, or property declaration
8782
8879
function checkVariableLikeDeclaration(node: VariableLikeDeclaration) {
8880
+ checkDecorators(node);
8783
8881
checkSourceElement(node.type);
8784
8882
// For a computed property, just check the initializer and exit
8785
8883
// Do not use hasDynamicName here, because that returns false for well known symbols.
@@ -8852,7 +8950,7 @@ module ts {
8852
8950
8853
8951
function checkVariableStatement(node: VariableStatement) {
8854
8952
// Grammar checking
8855
- checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node);
8953
+ checkGrammarDecorators(node) || checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node);
8856
8954
8857
8955
forEach(node.declarationList.declarations, checkSourceElement);
8858
8956
}
@@ -9483,7 +9581,7 @@ module ts {
9483
9581
function checkClassDeclaration(node: ClassDeclaration) {
9484
9582
// Grammar checking
9485
9583
checkGrammarClassDeclarationHeritageClauses(node);
9486
-
9584
+ checkDecorators(node);
9487
9585
if (node.name) {
9488
9586
checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
9489
9587
checkCollisionWithCapturedThisVariable(node, node.name);
@@ -9688,7 +9786,7 @@ module ts {
9688
9786
9689
9787
function checkInterfaceDeclaration(node: InterfaceDeclaration) {
9690
9788
// Grammar checking
9691
- checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
9789
+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
9692
9790
9693
9791
checkTypeParameters(node.typeParameters);
9694
9792
if (produceDiagnostics) {
@@ -9725,7 +9823,7 @@ module ts {
9725
9823
9726
9824
function checkTypeAliasDeclaration(node: TypeAliasDeclaration) {
9727
9825
// Grammar checking
9728
- checkGrammarModifiers(node);
9826
+ checkGrammarDecorators(node) || checkGrammarModifiers(node);
9729
9827
9730
9828
checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0);
9731
9829
checkSourceElement(node.type);
@@ -9894,7 +9992,7 @@ module ts {
9894
9992
}
9895
9993
9896
9994
// Grammar checking
9897
- checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node);
9995
+ checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node);
9898
9996
9899
9997
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
9900
9998
checkCollisionWithCapturedThisVariable(node, node.name);
@@ -9960,7 +10058,7 @@ module ts {
9960
10058
function checkModuleDeclaration(node: ModuleDeclaration) {
9961
10059
if (produceDiagnostics) {
9962
10060
// Grammar checking
9963
- if (!checkGrammarModifiers(node)) {
10061
+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node)) {
9964
10062
if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) {
9965
10063
grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names);
9966
10064
}
@@ -10055,7 +10153,7 @@ module ts {
10055
10153
}
10056
10154
10057
10155
function checkImportDeclaration(node: ImportDeclaration) {
10058
- if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10156
+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10059
10157
grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers);
10060
10158
}
10061
10159
if (checkExternalImportOrExportDeclaration(node)) {
@@ -10077,7 +10175,7 @@ module ts {
10077
10175
}
10078
10176
10079
10177
function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) {
10080
- checkGrammarModifiers(node);
10178
+ checkGrammarDecorators(node) || checkGrammarModifiers(node);
10081
10179
if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
10082
10180
checkImportBinding(node);
10083
10181
if (node.flags & NodeFlags.Export) {
@@ -10108,7 +10206,7 @@ module ts {
10108
10206
}
10109
10207
10110
10208
function checkExportDeclaration(node: ExportDeclaration) {
10111
- if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10209
+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10112
10210
grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers);
10113
10211
}
10114
10212
if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
@@ -10132,7 +10230,7 @@ module ts {
10132
10230
return;
10133
10231
}
10134
10232
// Grammar checking
10135
- if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10233
+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
10136
10234
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
10137
10235
}
10138
10236
if (node.expression) {
@@ -10232,6 +10330,8 @@ module ts {
10232
10330
case SyntaxKind.GetAccessor:
10233
10331
case SyntaxKind.SetAccessor:
10234
10332
return checkAccessorDeclaration(<AccessorDeclaration>node);
10333
+ case SyntaxKind.IncompleteDeclaration:
10334
+ return checkIncompleteDeclaration(<Declaration>node);
10235
10335
case SyntaxKind.TypeReference:
10236
10336
return checkTypeReference(<TypeReferenceNode>node);
10237
10337
case SyntaxKind.TypeQuery:
@@ -10436,6 +10536,10 @@ module ts {
10436
10536
links.flags |= NodeCheckFlags.EmitExtends;
10437
10537
}
10438
10538
10539
+ if (emitDecorate) {
10540
+ links.flags |= NodeCheckFlags.EmitDecorate;
10541
+ }
10542
+
10439
10543
links.flags |= NodeCheckFlags.TypeChecked;
10440
10544
}
10441
10545
}
@@ -11235,6 +11339,12 @@ module ts {
11235
11339
globalNumberType = getGlobalType("Number");
11236
11340
globalBooleanType = getGlobalType("Boolean");
11237
11341
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");
11238
11348
11239
11349
// If we're in ES6 mode, load the TemplateStringsArray.
11240
11350
// Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios.
@@ -11259,6 +11369,42 @@ module ts {
11259
11369
11260
11370
11261
11371
// 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
+
11262
11408
function checkGrammarModifiers(node: Node): boolean {
11263
11409
switch (node.kind) {
11264
11410
case SyntaxKind.GetAccessor:
@@ -11455,7 +11601,7 @@ module ts {
11455
11601
function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
11456
11602
// Prevent cascading error by short-circuit
11457
11603
let file = getSourceFileOfNode(node);
11458
- return checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) ||
11604
+ return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) ||
11459
11605
checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
11460
11606
}
11461
11607
@@ -11512,7 +11658,7 @@ module ts {
11512
11658
11513
11659
function checkGrammarIndexSignature(node: SignatureDeclaration) {
11514
11660
// Prevent cascading error by short-circuit
11515
- checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node) || checkGrammarForIndexSignatureModifier(node);
11661
+ return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node) || checkGrammarForIndexSignatureModifier(node);
11516
11662
}
11517
11663
11518
11664
function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray<TypeNode>): boolean {
@@ -11561,7 +11707,7 @@ module ts {
11561
11707
let seenExtendsClause = false;
11562
11708
let seenImplementsClause = false;
11563
11709
11564
- if (!checkGrammarModifiers(node) && node.heritageClauses) {
11710
+ if (!checkGrammarDecorators(node) && ! checkGrammarModifiers(node) && node.heritageClauses) {
11565
11711
for (let heritageClause of node.heritageClauses) {
11566
11712
if (heritageClause.token === SyntaxKind.ExtendsKeyword) {
11567
11713
if (seenExtendsClause) {
0 commit comments