Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
27 changes: 27 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -919,6 +945,7 @@ module ts {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.MethodSignature:
case SyntaxKind.IndexSignature:
return true;
default:
Expand Down
14 changes: 14 additions & 0 deletions tests/baselines/reference/decoratorOnClassMethod11.errors.txt
Original file line number Diff line number Diff line change
@@ -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() { }
}
}
32 changes: 32 additions & 0 deletions tests/baselines/reference/decoratorOnClassMethod11.js
Original file line number Diff line number Diff line change
@@ -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 = {}));
15 changes: 15 additions & 0 deletions tests/baselines/reference/decoratorOnClassMethod12.errors.txt
Original file line number Diff line number Diff line change
@@ -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() { }
}
}
46 changes: 46 additions & 0 deletions tests/baselines/reference/decoratorOnClassMethod12.js
Original file line number Diff line number Diff line change
@@ -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 = {}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @target: ES5
module M {
class C {
decorator(target: Object, key: string): void { }

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