Merge pull request #2658 from Microsoft/fixDecoratorBindingForSuperThis

Fixes #2601, incorrect resolution of this/super
This commit is contained in:
Ron Buckton 2015-04-07 19:10:03 -07:00
commit 68b38b3e6a
8 changed files with 154 additions and 1 deletions

View File

@ -5600,7 +5600,7 @@ module ts {
}
}
if (container.kind === SyntaxKind.ComputedPropertyName) {
if (container && container.kind === SyntaxKind.ComputedPropertyName) {
error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
}
else if (isCallExpression) {

View File

@ -526,6 +526,19 @@ module ts {
// the *body* of the container.
node = node.parent;
break;
case SyntaxKind.Decorator:
// Decorators are always applied outside of the body of a class or method.
if (node.parent.kind === SyntaxKind.Parameter && isClassElement(node.parent.parent)) {
// If the decorator's parent is a Parameter, we resolve the this container from
// the grandparent class declaration.
node = node.parent.parent;
}
else if (isClassElement(node.parent)) {
// If the decorator's parent is a class element, we resolve the 'this' container
// from the parent class declaration.
node = node.parent;
}
break;
case SyntaxKind.ArrowFunction:
if (!includeArrowFunctions) {
continue;
@ -568,6 +581,19 @@ module ts {
// the *body* of the container.
node = node.parent;
break;
case SyntaxKind.Decorator:
// Decorators are always applied outside of the body of a class or method.
if (node.parent.kind === SyntaxKind.Parameter && isClassElement(node.parent.parent)) {
// If the decorator's parent is a Parameter, we resolve the this container from
// the grandparent class declaration.
node = node.parent.parent;
}
else if (isClassElement(node.parent)) {
// If the decorator's parent is a class element, we resolve the 'this' container
// from the parent class declaration.
node = node.parent;
}
break;
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
@ -919,6 +945,7 @@ module ts {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.MethodSignature:
case SyntaxKind.IndexSignature:
return true;
default:

View File

@ -0,0 +1,14 @@
tests/cases/conformance/decorators/class/method/decoratorOnClassMethod11.ts(5,10): error TS2331: 'this' cannot be referenced in a module body.
==== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod11.ts (1 errors) ====
module M {
class C {
decorator(target: Object, key: string): void { }
@this.decorator
~~~~
!!! error TS2331: 'this' cannot be referenced in a module body.
method() { }
}
}

View File

@ -0,0 +1,32 @@
//// [decoratorOnClassMethod11.ts]
module M {
class C {
decorator(target: Object, key: string): void { }
@this.decorator
method() { }
}
}
//// [decoratorOnClassMethod11.js]
var __decorate = this.__decorate || (typeof Reflect === "object" && Reflect.decorate) || function (decorators, target, key, desc) {
switch (arguments.length) {
case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
}
};
var M;
(function (M) {
var C = (function () {
function C() {
}
C.prototype.decorator = function (target, key) { };
C.prototype.method = function () { };
Object.defineProperty(C.prototype, "method",
__decorate([
this.decorator
], C.prototype, "method", Object.getOwnPropertyDescriptor(C.prototype, "method")));
return C;
})();
})(M || (M = {}));

View File

@ -0,0 +1,15 @@
tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts(6,10): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class
==== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts (1 errors) ====
module M {
class S {
decorator(target: Object, key: string): void { }
}
class C extends S {
@super.decorator
~~~~~
!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class
method() { }
}
}

View File

@ -0,0 +1,46 @@
//// [decoratorOnClassMethod12.ts]
module M {
class S {
decorator(target: Object, key: string): void { }
}
class C extends S {
@super.decorator
method() { }
}
}
//// [decoratorOnClassMethod12.js]
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var __decorate = this.__decorate || (typeof Reflect === "object" && Reflect.decorate) || function (decorators, target, key, desc) {
switch (arguments.length) {
case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
}
};
var M;
(function (M) {
var S = (function () {
function S() {
}
S.prototype.decorator = function (target, key) { };
return S;
})();
var C = (function (_super) {
__extends(C, _super);
function C() {
_super.apply(this, arguments);
}
C.prototype.method = function () { };
Object.defineProperty(C.prototype, "method",
__decorate([
_super.decorator
], C.prototype, "method", Object.getOwnPropertyDescriptor(C.prototype, "method")));
return C;
})(S);
})(M || (M = {}));

View File

@ -0,0 +1,9 @@
// @target: ES5
module M {
class C {
decorator(target: Object, key: string): void { }
@this.decorator
method() { }
}
}

View File

@ -0,0 +1,10 @@
// @target: ES5
module M {
class S {
decorator(target: Object, key: string): void { }
}
class C extends S {
@super.decorator
method() { }
}
}