Fix decorated accessor emit (#26016) (#26103)

This commit is contained in:
Wesley Wigham
2018-07-31 18:22:54 -07:00
committed by GitHub
parent 20bf93a77a
commit 9b95d562dd
9 changed files with 181 additions and 16 deletions

View File

@@ -5092,20 +5092,25 @@ namespace ts {
}
}
function getAnnotatedAccessorType(accessor: AccessorDeclaration | undefined): Type | undefined {
function getAnnotatedAccessorTypeNode(accessor: AccessorDeclaration | undefined): TypeNode | undefined {
if (accessor) {
if (accessor.kind === SyntaxKind.GetAccessor) {
const getterTypeAnnotation = getEffectiveReturnTypeNode(accessor);
return getterTypeAnnotation && getTypeFromTypeNode(getterTypeAnnotation);
return getterTypeAnnotation;
}
else {
const setterTypeAnnotation = getEffectiveSetAccessorTypeAnnotationNode(accessor);
return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation);
return setterTypeAnnotation;
}
}
return undefined;
}
function getAnnotatedAccessorType(accessor: AccessorDeclaration | undefined): Type | undefined {
const node = getAnnotatedAccessorTypeNode(accessor);
return node && getTypeFromTypeNode(node);
}
function getAnnotatedAccessorThisParameter(accessor: AccessorDeclaration): Symbol | undefined {
const parameter = getAccessorThisParameter(accessor);
return parameter && parameter.symbol;
@@ -23342,9 +23347,13 @@ namespace ts {
}
break;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(node as AccessorDeclaration), otherKind);
markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node as AccessorDeclaration) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor));
break;
case SyntaxKind.MethodDeclaration:
for (const parameter of (<FunctionLikeDeclaration>node).parameters) {
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
}
@@ -27867,8 +27876,8 @@ namespace ts {
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(accessor), otherKind);
const firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor;
const secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor;
const setAccessor = accessor.kind === SyntaxKind.SetAccessor ? accessor : otherAccessor;
const getAccessor = accessor.kind === SyntaxKind.GetAccessor ? accessor : otherAccessor;
const setAccessor = accessor.kind === SyntaxKind.SetAccessor ? accessor : otherAccessor as SetAccessorDeclaration;
const getAccessor = accessor.kind === SyntaxKind.GetAccessor ? accessor : otherAccessor as GetAccessorDeclaration;
return {
firstAccessor,
secondAccessor,

View File

@@ -1750,6 +1750,12 @@ namespace ts {
type SerializedEntityNameAsExpression = Identifier | BinaryExpression | PropertyAccessExpression;
type SerializedTypeNode = SerializedEntityNameAsExpression | VoidExpression | ConditionalExpression;
function getAccessorTypeNode(node: AccessorDeclaration) {
const accessors = resolver.getAllAccessorDeclarations(node);
return accessors.setAccessor && getSetAccessorTypeAnnotationNode(accessors.setAccessor)
|| accessors.getAccessor && getEffectiveReturnTypeNode(accessors.getAccessor);
}
/**
* Serializes the type of a node for use with decorator type metadata.
*
@@ -1759,10 +1765,10 @@ namespace ts {
switch (node.kind) {
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.Parameter:
case SyntaxKind.GetAccessor:
return serializeTypeNode((<PropertyDeclaration | ParameterDeclaration | GetAccessorDeclaration>node).type);
case SyntaxKind.SetAccessor:
return serializeTypeNode(getSetAccessorTypeAnnotationNode(<SetAccessorDeclaration>node));
case SyntaxKind.GetAccessor:
return serializeTypeNode(getAccessorTypeNode(node as AccessorDeclaration));
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.MethodDeclaration:

View File

@@ -3305,8 +3305,8 @@ namespace ts {
export interface AllAccessorDeclarations {
firstAccessor: AccessorDeclaration;
secondAccessor: AccessorDeclaration | undefined;
getAccessor: AccessorDeclaration | undefined;
setAccessor: AccessorDeclaration | undefined;
getAccessor: GetAccessorDeclaration | undefined;
setAccessor: SetAccessorDeclaration | undefined;
}
/** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */

View File

@@ -3293,8 +3293,8 @@ namespace ts {
// TODO: GH#18217
let firstAccessor!: AccessorDeclaration;
let secondAccessor!: AccessorDeclaration;
let getAccessor!: AccessorDeclaration;
let setAccessor!: AccessorDeclaration;
let getAccessor!: GetAccessorDeclaration;
let setAccessor!: SetAccessorDeclaration;
if (hasDynamicName(accessor)) {
firstAccessor = accessor;
if (accessor.kind === SyntaxKind.GetAccessor) {
@@ -3322,11 +3322,11 @@ namespace ts {
}
if (member.kind === SyntaxKind.GetAccessor && !getAccessor) {
getAccessor = <AccessorDeclaration>member;
getAccessor = <GetAccessorDeclaration>member;
}
if (member.kind === SyntaxKind.SetAccessor && !setAccessor) {
setAccessor = <AccessorDeclaration>member;
setAccessor = <SetAccessorDeclaration>member;
}
}
}

View File

@@ -50,7 +50,7 @@ var A = /** @class */ (function () {
});
__decorate([
dec,
__metadata("design:type", Object),
__metadata("design:type", Number),
__metadata("design:paramtypes", [Number])
], A.prototype, "x", null);
return A;
@@ -98,7 +98,7 @@ var D = /** @class */ (function () {
});
__decorate([
dec,
__metadata("design:type", Object),
__metadata("design:type", Number),
__metadata("design:paramtypes", [Number])
], D.prototype, "x", null);
return D;

View File

@@ -0,0 +1,54 @@
//// [tests/cases/compiler/targetEs6DecoratorMetadataImportNotElided.ts] ////
//// [deps.ts]
export function Input(): any { }
export class TemplateRef { }
//// [index.ts]
import { Input, TemplateRef } from './deps';
export class MyComponent {
_ref: TemplateRef;
@Input()
get ref() { return this._ref; }
set ref(value: TemplateRef) { this._ref = value; }
}
//// [deps.js]
export function Input() { }
var TemplateRef = /** @class */ (function () {
function TemplateRef() {
}
return TemplateRef;
}());
export { TemplateRef };
//// [index.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Input, TemplateRef } from './deps';
var MyComponent = /** @class */ (function () {
function MyComponent() {
}
Object.defineProperty(MyComponent.prototype, "ref", {
get: function () { return this._ref; },
set: function (value) { this._ref = value; },
enumerable: true,
configurable: true
});
__decorate([
Input(),
__metadata("design:type", TemplateRef),
__metadata("design:paramtypes", [TemplateRef])
], MyComponent.prototype, "ref", null);
return MyComponent;
}());
export { MyComponent };

View File

@@ -0,0 +1,38 @@
=== tests/cases/compiler/deps.ts ===
export function Input(): any { }
>Input : Symbol(Input, Decl(deps.ts, 0, 0))
export class TemplateRef { }
>TemplateRef : Symbol(TemplateRef, Decl(deps.ts, 0, 32))
=== tests/cases/compiler/index.ts ===
import { Input, TemplateRef } from './deps';
>Input : Symbol(Input, Decl(index.ts, 0, 8))
>TemplateRef : Symbol(TemplateRef, Decl(index.ts, 0, 15))
export class MyComponent {
>MyComponent : Symbol(MyComponent, Decl(index.ts, 0, 44))
_ref: TemplateRef;
>_ref : Symbol(MyComponent._ref, Decl(index.ts, 2, 26))
>TemplateRef : Symbol(TemplateRef, Decl(index.ts, 0, 15))
@Input()
>Input : Symbol(Input, Decl(index.ts, 0, 8))
get ref() { return this._ref; }
>ref : Symbol(MyComponent.ref, Decl(index.ts, 3, 22), Decl(index.ts, 6, 35))
>this._ref : Symbol(MyComponent._ref, Decl(index.ts, 2, 26))
>this : Symbol(MyComponent, Decl(index.ts, 0, 44))
>_ref : Symbol(MyComponent._ref, Decl(index.ts, 2, 26))
set ref(value: TemplateRef) { this._ref = value; }
>ref : Symbol(MyComponent.ref, Decl(index.ts, 3, 22), Decl(index.ts, 6, 35))
>value : Symbol(value, Decl(index.ts, 7, 12))
>TemplateRef : Symbol(TemplateRef, Decl(index.ts, 0, 15))
>this._ref : Symbol(MyComponent._ref, Decl(index.ts, 2, 26))
>this : Symbol(MyComponent, Decl(index.ts, 0, 44))
>_ref : Symbol(MyComponent._ref, Decl(index.ts, 2, 26))
>value : Symbol(value, Decl(index.ts, 7, 12))
}

View File

@@ -0,0 +1,40 @@
=== tests/cases/compiler/deps.ts ===
export function Input(): any { }
>Input : () => any
export class TemplateRef { }
>TemplateRef : TemplateRef
=== tests/cases/compiler/index.ts ===
import { Input, TemplateRef } from './deps';
>Input : () => any
>TemplateRef : typeof TemplateRef
export class MyComponent {
>MyComponent : MyComponent
_ref: TemplateRef;
>_ref : TemplateRef
>TemplateRef : TemplateRef
@Input()
>Input() : any
>Input : () => any
get ref() { return this._ref; }
>ref : TemplateRef
>this._ref : TemplateRef
>this : this
>_ref : TemplateRef
set ref(value: TemplateRef) { this._ref = value; }
>ref : TemplateRef
>value : TemplateRef
>TemplateRef : TemplateRef
>this._ref = value : TemplateRef
>this._ref : TemplateRef
>this : this
>_ref : TemplateRef
>value : TemplateRef
}

View File

@@ -0,0 +1,18 @@
// @module: es6
// @target: es5
// @emitDecoratorMetadata: true
// @experimentalDecorators: true
// @filename: deps.ts
export function Input(): any { }
export class TemplateRef { }
// @filename: index.ts
import { Input, TemplateRef } from './deps';
export class MyComponent {
_ref: TemplateRef;
@Input()
get ref() { return this._ref; }
set ref(value: TemplateRef) { this._ref = value; }
}