Merge pull request #5294 from Microsoft/fixDecoratorSwitch

Fixes an issue with decorators when compiling using tsc.exe
This commit is contained in:
Ron Buckton 2015-10-16 14:54:07 -07:00
Родитель 302db0a9d5 81e784c01e
Коммит 5b9469850a
1 изменённых файлов: 95 добавлений и 100 удалений

Просмотреть файл

@ -8646,39 +8646,36 @@ namespace ts {
*/
function getEffectiveDecoratorFirstArgumentType(node: Node): Type {
// The first argument to a decorator is its `target`.
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
// For a class decorator, the `target` is the type of the class (e.g. the
// "static" or "constructor" side of the class)
if (node.kind === SyntaxKind.ClassDeclaration) {
// For a class decorator, the `target` is the type of the class (e.g. the
// "static" or "constructor" side of the class)
let classSymbol = getSymbolOfNode(node);
return getTypeOfSymbol(classSymbol);
}
if (node.kind === SyntaxKind.Parameter) {
// For a parameter decorator, the `target` is the parent type of the
// parameter's containing method.
node = node.parent;
if (node.kind === SyntaxKind.Constructor) {
let classSymbol = getSymbolOfNode(node);
return getTypeOfSymbol(classSymbol);
case SyntaxKind.Parameter:
// For a parameter decorator, the `target` is the parent type of the
// parameter's containing method.
node = node.parent;
if (node.kind === SyntaxKind.Constructor) {
let classSymbol = getSymbolOfNode(node);
return getTypeOfSymbol(classSymbol);
}
// fall-through
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
// For a property or method decorator, the `target` is the
// "static"-side type of the parent of the member if the member is
// declared "static"; otherwise, it is the "instance"-side type of the
// parent of the member.
return getParentTypeOfClassElement(<ClassElement>node);
default:
Debug.fail("Unsupported decorator target.");
return unknownType;
}
}
if (node.kind === SyntaxKind.PropertyDeclaration ||
node.kind === SyntaxKind.MethodDeclaration ||
node.kind === SyntaxKind.GetAccessor ||
node.kind === SyntaxKind.SetAccessor) {
// For a property or method decorator, the `target` is the
// "static"-side type of the parent of the member if the member is
// declared "static"; otherwise, it is the "instance"-side type of the
// parent of the member.
return getParentTypeOfClassElement(<ClassElement>node);
}
Debug.fail("Unsupported decorator target.");
return unknownType;
}
/**
@ -8698,57 +8695,54 @@ namespace ts {
*/
function getEffectiveDecoratorSecondArgumentType(node: Node) {
// The second argument to a decorator is its `propertyKey`
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
Debug.fail("Class decorators should not have a second synthetic argument.");
return unknownType;
if (node.kind === SyntaxKind.ClassDeclaration) {
Debug.fail("Class decorators should not have a second synthetic argument.");
return unknownType;
}
case SyntaxKind.Parameter:
node = node.parent;
if (node.kind === SyntaxKind.Constructor) {
// For a constructor parameter decorator, the `propertyKey` will be `undefined`.
return anyType;
}
if (node.kind === SyntaxKind.Parameter) {
node = node.parent;
if (node.kind === SyntaxKind.Constructor) {
// For a constructor parameter decorator, the `propertyKey` will be `undefined`.
return anyType;
}
// For a non-constructor parameter decorator, the `propertyKey` will be either
// a string or a symbol, based on the name of the parameter's containing method.
// fall-through
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
// The `propertyKey` for a property or method decorator will be a
// string literal type if the member name is an identifier, number, or string;
// otherwise, if the member name is a computed property name it will
// be either string or symbol.
let element = <ClassElement>node;
switch (element.name.kind) {
case SyntaxKind.Identifier:
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
return getStringLiteralType(<StringLiteral>element.name);
case SyntaxKind.ComputedPropertyName:
let nameType = checkComputedPropertyName(<ComputedPropertyName>element.name);
if (allConstituentTypesHaveKind(nameType, TypeFlags.ESSymbol)) {
return nameType;
}
else {
return stringType;
}
default:
Debug.fail("Unsupported property name.");
return unknownType;
}
default:
Debug.fail("Unsupported decorator target.");
return unknownType;
}
if (node.kind === SyntaxKind.PropertyDeclaration ||
node.kind === SyntaxKind.MethodDeclaration ||
node.kind === SyntaxKind.GetAccessor ||
node.kind === SyntaxKind.SetAccessor) {
// The `propertyKey` for a property or method decorator will be a
// string literal type if the member name is an identifier, number, or string;
// otherwise, if the member name is a computed property name it will
// be either string or symbol.
let element = <ClassElement>node;
switch (element.name.kind) {
case SyntaxKind.Identifier:
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
return getStringLiteralType(<StringLiteral>element.name);
case SyntaxKind.ComputedPropertyName:
let nameType = checkComputedPropertyName(<ComputedPropertyName>element.name);
if (allConstituentTypesHaveKind(nameType, TypeFlags.ESSymbol)) {
return nameType;
}
else {
return stringType;
}
default:
Debug.fail("Unsupported property name.");
return unknownType;
}
}
Debug.fail("Unsupported decorator target.");
return unknownType;
}
/**
@ -8761,31 +8755,32 @@ namespace ts {
function getEffectiveDecoratorThirdArgumentType(node: Node) {
// The third argument to a decorator is either its `descriptor` for a method decorator
// or its `parameterIndex` for a paramter decorator
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
Debug.fail("Class decorators should not have a third synthetic argument.");
return unknownType;
case SyntaxKind.Parameter:
// The `parameterIndex` for a parameter decorator is always a number
return numberType;
case SyntaxKind.PropertyDeclaration:
Debug.fail("Property decorators should not have a third synthetic argument.");
return unknownType;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
// The `descriptor` for a method decorator will be a `TypedPropertyDescriptor<T>`
// for the type of the member.
let propertyType = getTypeOfNode(node);
return createTypedPropertyDescriptorType(propertyType);
default:
Debug.fail("Unsupported decorator target.");
return unknownType;
if (node.kind === SyntaxKind.ClassDeclaration) {
Debug.fail("Class decorators should not have a third synthetic argument.");
return unknownType;
}
if (node.kind === SyntaxKind.Parameter) {
// The `parameterIndex` for a parameter decorator is always a number
return numberType;
}
if (node.kind === SyntaxKind.PropertyDeclaration) {
Debug.fail("Property decorators should not have a third synthetic argument.");
return unknownType;
}
if (node.kind === SyntaxKind.MethodDeclaration ||
node.kind === SyntaxKind.GetAccessor ||
node.kind === SyntaxKind.SetAccessor) {
// The `descriptor` for a method decorator will be a `TypedPropertyDescriptor<T>`
// for the type of the member.
let propertyType = getTypeOfNode(node);
return createTypedPropertyDescriptorType(propertyType);
}
Debug.fail("Unsupported decorator target.");
return unknownType;
}
/**