Simplified grammar check for decorators.

This commit is contained in:
Ron Buckton 2015-03-20 17:42:27 -07:00
parent 299fbe3719
commit 6633349b72
2 changed files with 34 additions and 35 deletions

View file

@ -11402,42 +11402,41 @@ module ts {
// GRAMMAR CHECKING
function isValidDecoratorTarget(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
// classes are valid targets
return true;
case SyntaxKind.PropertyDeclaration:
// property declarations are valid if their parent is a class declaration.
return node.parent.kind === SyntaxKind.ClassDeclaration;
case SyntaxKind.Parameter:
// if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
return (<FunctionLikeDeclaration>node.parent).body && node.parent.parent.kind === SyntaxKind.ClassDeclaration;
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.MethodDeclaration:
// if this method has a body and its parent is a class declaration, this is a valid target.
return (<FunctionLikeDeclaration>node).body && node.parent.kind === SyntaxKind.ClassDeclaration;
}
return false;
}
function checkGrammarDecorators(node: Node): boolean {
if (!node.decorators) {
return false;
}
let target = node;
while (target) {
switch (target.kind) {
case SyntaxKind.ClassDeclaration:
if (languageVersion < ScriptTarget.ES5) {
return grammarErrorOnNode(node, Diagnostics.Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher);
}
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;
if (languageVersion < ScriptTarget.ES5) {
return grammarErrorOnNode(node, Diagnostics.Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher);
}
return grammarErrorOnNode(node, Diagnostics.Decorators_are_not_valid_here);
else if (!isValidDecoratorTarget(node)) {
return grammarErrorOnNode(node, Diagnostics.Decorators_are_not_valid_here);
}
return false;
}
function checkGrammarModifiers(node: Node): boolean {
@ -12322,7 +12321,7 @@ module ts {
}
function checkGrammarTopLevelElementForRequiredDeclareModifier(node: Node): boolean {
// A declare modifier is required for any top level .d.ts declaration except export=, interfaces and imports:
// A declare modifier is required for any top level .d.ts declaration except export=, interfaces, and imports:
// categories:
//
// DeclarationElement:

6
src/lib/core.d.ts vendored
View file

@ -1165,6 +1165,6 @@ interface TypedPropertyDescriptor<T> {
set?: (value: T) => void;
}
interface ClassDecorator { <TFunction extends Function>(target: TFunction): TFunction | void; }
interface PropertyDecorator { <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void; }
interface ParameterDecorator { (target: Function, parameterIndex: number): void; }
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Function, parameterIndex: number) => void;