Merge pull request #12782 from Microsoft/fix12439

Fix paramtypes metadata emit
This commit is contained in:
Mohamed Hegazy
2016-12-12 16:22:34 -08:00
committed by GitHub
17 changed files with 501 additions and 55 deletions

View File

@@ -1277,7 +1277,7 @@ namespace ts {
* @param node The declaration node.
* @param allDecorators An object containing all of the decorators for the declaration.
*/
function transformAllDecoratorsOfDeclaration(node: Declaration, allDecorators: AllDecorators) {
function transformAllDecoratorsOfDeclaration(node: Declaration, container: ClassLikeDeclaration, allDecorators: AllDecorators) {
if (!allDecorators) {
return undefined;
}
@@ -1285,7 +1285,7 @@ namespace ts {
const decoratorExpressions: Expression[] = [];
addRange(decoratorExpressions, map(allDecorators.decorators, transformDecorator));
addRange(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
addTypeMetadata(node, decoratorExpressions);
addTypeMetadata(node, container, decoratorExpressions);
return decoratorExpressions;
}
@@ -1334,7 +1334,7 @@ namespace ts {
*/
function generateClassElementDecorationExpression(node: ClassExpression | ClassDeclaration, member: ClassElement) {
const allDecorators = getAllDecoratorsOfClassElement(node, member);
const decoratorExpressions = transformAllDecoratorsOfDeclaration(member, allDecorators);
const decoratorExpressions = transformAllDecoratorsOfDeclaration(member, node, allDecorators);
if (!decoratorExpressions) {
return undefined;
}
@@ -1415,7 +1415,7 @@ namespace ts {
*/
function generateConstructorDecorationExpression(node: ClassExpression | ClassDeclaration) {
const allDecorators = getAllDecoratorsOfConstructor(node);
const decoratorExpressions = transformAllDecoratorsOfDeclaration(node, allDecorators);
const decoratorExpressions = transformAllDecoratorsOfDeclaration(node, node, allDecorators);
if (!decoratorExpressions) {
return undefined;
}
@@ -1468,22 +1468,22 @@ namespace ts {
* @param node The declaration node.
* @param decoratorExpressions The destination array to which to add new decorator expressions.
*/
function addTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) {
function addTypeMetadata(node: Declaration, container: ClassLikeDeclaration, decoratorExpressions: Expression[]) {
if (USE_NEW_TYPE_METADATA_FORMAT) {
addNewTypeMetadata(node, decoratorExpressions);
addNewTypeMetadata(node, container, decoratorExpressions);
}
else {
addOldTypeMetadata(node, decoratorExpressions);
addOldTypeMetadata(node, container, decoratorExpressions);
}
}
function addOldTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) {
function addOldTypeMetadata(node: Declaration, container: ClassLikeDeclaration, decoratorExpressions: Expression[]) {
if (compilerOptions.emitDecoratorMetadata) {
if (shouldAddTypeMetadata(node)) {
decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node)));
}
if (shouldAddParamTypesMetadata(node)) {
decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node)));
decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container)));
}
if (shouldAddReturnTypeMetadata(node)) {
decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node)));
@@ -1491,14 +1491,14 @@ namespace ts {
}
}
function addNewTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) {
function addNewTypeMetadata(node: Declaration, container: ClassLikeDeclaration, decoratorExpressions: Expression[]) {
if (compilerOptions.emitDecoratorMetadata) {
let properties: ObjectLiteralElementLike[];
if (shouldAddTypeMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeTypeOfNode(node))));
}
if (shouldAddParamTypesMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeParameterTypesOfNode(node))));
(properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeParameterTypesOfNode(node, container))));
}
if (shouldAddReturnTypeMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node))));
@@ -1543,12 +1543,16 @@ namespace ts {
* @param node The node to test.
*/
function shouldAddParamTypesMetadata(node: Declaration): boolean {
const kind = node.kind;
return kind === SyntaxKind.ClassDeclaration
|| kind === SyntaxKind.ClassExpression
|| kind === SyntaxKind.MethodDeclaration
|| kind === SyntaxKind.GetAccessor
|| kind === SyntaxKind.SetAccessor;
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
return getFirstConstructorWithBody(<ClassLikeDeclaration>node) !== undefined;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return true;
}
return false;
}
/**
@@ -1596,7 +1600,7 @@ namespace ts {
*
* @param node The node that should have its parameter types serialized.
*/
function serializeParameterTypesOfNode(node: Node): Expression {
function serializeParameterTypesOfNode(node: Node, container: ClassLikeDeclaration): Expression {
const valueDeclaration =
isClassLike(node)
? getFirstConstructorWithBody(node)
@@ -1606,7 +1610,7 @@ namespace ts {
const expressions: Expression[] = [];
if (valueDeclaration) {
const parameters = valueDeclaration.parameters;
const parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container);
const numParameters = parameters.length;
for (let i = 0; i < numParameters; i++) {
const parameter = parameters[i];
@@ -1625,6 +1629,16 @@ namespace ts {
return createArrayLiteral(expressions);
}
function getParametersOfDecoratedDeclaration(node: FunctionLikeDeclaration, container: ClassLikeDeclaration) {
if (container && node.kind === SyntaxKind.GetAccessor) {
const { setAccessor } = getAllAccessorDeclarations(container.members, <AccessorDeclaration>node);
if (setAccessor) {
return setAccessor.parameters;
}
}
return node.parameters;
}
/**
* Serializes the return type of a node for use with decorator type metadata.
*