Skip to content
This repository was archived by the owner on May 19, 2018. It is now read-only.

Decorators Stage 2 Parsing #587

Merged
merged 14 commits into from
Jun 22, 2017
Merged
Prev Previous commit
Next Next commit
Disallow in object literals, params, class props
And add tests to reflect the same
  • Loading branch information
peey committed Jun 17, 2017
commit 9c639743dd0ea8c4f33f77232bb3b95698cfcd92
12 changes: 10 additions & 2 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -847,8 +847,16 @@ export default class ExpressionParser extends LValParser {
if (this.eat(tt.braceR)) break;
}

while (this.match(tt.at)) {
decorators.push(this.parseDecorator());
if (this.match(tt.at)) {
if (this.hasPlugin("decorators-stage-2")) {
this.raise(this.state.start, "decorators-stage-2 disallows object literal property decorators");
} else {
// we needn't check if decorators (stage 0) plugin is enabled since it's checked by
// the call to this.parseDecorator
while (this.match(tt.at)) {
decorators.push(this.parseDecorator());
}
}
}

let prop = this.startNode(), isGenerator = false, isAsync = false, startPos, startLoc;
Expand Down
3 changes: 3 additions & 0 deletions src/parser/lval.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ export default class LValParser extends NodeUtils {
break;
} else {
const decorators = [];
if (this.match(tt.at) && this.hasPlugin("decorators-stage-2")) {
this.raise(this.state.start, "Stage 2 decorators cannot be used to decorate parameters");
}
while (this.match(tt.at)) {
decorators.push(this.parseDecorator());
}
Expand Down
5 changes: 5 additions & 0 deletions src/parser/statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,10 @@ export default class StatementParser extends ExpressionParser {
}

this.parseClassMember(classBody, member, state);

if (this.hasPlugin("decorators-stage-2") && member.kind != "method" && member.decorators && member.decorators.length > 0) {
this.raise(member.start, "Stage 2 decorators may only be used with a class or a class method");
}
}

if (decorators.length) {
Expand Down Expand Up @@ -776,6 +780,7 @@ export default class StatementParser extends ExpressionParser {
if (!methodOrProp.computed && methodOrProp.static && (methodOrProp.key.name === "prototype" || methodOrProp.key.value === "prototype")) {
this.raise(methodOrProp.key.start, "Classes may not have static property named prototype");
}

if (this.isClassMethod()) {
// a normal method
if (this.isNonstaticConstructor(method)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@foo('bar')
class Foo {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
{
"type": "File",
"start": 0,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 12
}
},
"program": {
"type": "Program",
"start": 0,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 12
}
},
"sourceType": "script",
"body": [
{
"type": "ClassDeclaration",
"start": 12,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 12
}
},
"decorators": [
{
"type": "Decorator",
"start": 0,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 11
}
},
"expression": {
"type": "CallExpression",
"start": 1,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 11
}
},
"callee": {
"type": "Identifier",
"start": 1,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 4
},
"identifierName": "foo"
},
"name": "foo"
},
"arguments": [
{
"type": "StringLiteral",
"start": 5,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 10
}
},
"extra": {
"rawValue": "bar",
"raw": "'bar'"
},
"value": "bar"
}
]
}
}
],
"id": {
"type": "Identifier",
"start": 18,
"end": 21,
"loc": {
"start": {
"line": 2,
"column": 6
},
"end": {
"line": 2,
"column": 9
},
"identifierName": "Foo"
},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 22,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 12
}
},
"body": []
}
}
],
"directives": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@abc
class Foo {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"type": "File",
"start": 0,
"end": 19,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 19,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
},
"sourceType": "script",
"body": [
{
"type": "ClassDeclaration",
"start": 5,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
},
"decorators": [
{
"type": "Decorator",
"start": 0,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 4
}
},
"expression": {
"type": "Identifier",
"start": 1,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 4
},
"identifierName": "abc"
},
"name": "abc"
}
}
],
"id": {
"type": "Identifier",
"start": 11,
"end": 14,
"loc": {
"start": {
"line": 2,
"column": 6
},
"end": {
"line": 2,
"column": 9
},
"identifierName": "Foo"
},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 15,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 4,
"column": 1
}
},
"body": []
}
}
],
"directives": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Foo {
constructor(@foo x) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"throws": "Stage 2 decorators cannot be used to decorate parameters (2:14)"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Foo {
@foo[bar] a = 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"plugins": ["decorators-stage-2", "classProperties"],
"throws": "Unexpected token (2:12)"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Foo {
@bar[bizz]
abc() {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"plugins": ["decorators-stage-2", "classProperties"],
"throws": "Stage 2 decorators may only be used with a class or a class method (2:6)"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@foo
export default class {}
Loading