make parsing of decorators stateless - fixes shuhei/babel-angular2-app#4
This commit is contained in:
@@ -509,22 +509,24 @@ pp.parseTemplate = function() {
|
||||
pp.parseObj = function(isPattern, refShorthandDefaultPos) {
|
||||
let node = this.startNode(), first = true, propHash = {}
|
||||
node.properties = []
|
||||
let decorators = []
|
||||
this.next()
|
||||
while (!this.eat(tt.braceR)) {
|
||||
if (!first) {
|
||||
this.expect(tt.comma)
|
||||
if (this.afterTrailingComma(tt.braceR)) break
|
||||
} else first = false
|
||||
|
||||
while (this.type === tt.at) {
|
||||
this.decorators.push(this.parseDecorator())
|
||||
decorators.push(this.parseDecorator())
|
||||
}
|
||||
|
||||
let prop = this.startNode(), isGenerator = false, isAsync = false, start
|
||||
if (decorators.length) {
|
||||
prop.decorators = decorators
|
||||
decorators = []
|
||||
}
|
||||
if (this.options.features["es7.objectRestSpread"] && this.type === tt.ellipsis) {
|
||||
prop = this.parseSpread()
|
||||
prop.type = "SpreadProperty"
|
||||
this.takeDecorators(prop)
|
||||
node.properties.push(prop)
|
||||
continue
|
||||
}
|
||||
@@ -550,10 +552,9 @@ pp.parseObj = function(isPattern, refShorthandDefaultPos) {
|
||||
}
|
||||
this.parseObjPropValue(prop, start, isGenerator, isAsync, isPattern, refShorthandDefaultPos);
|
||||
this.checkPropClash(prop, propHash)
|
||||
this.takeDecorators(prop)
|
||||
node.properties.push(this.finishNode(prop, "Property"))
|
||||
}
|
||||
if (this.decorators.length) {
|
||||
if (decorators.length) {
|
||||
this.raise(this.start, "You have trailing decorators with no property");
|
||||
}
|
||||
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
|
||||
|
||||
@@ -471,14 +471,18 @@ pp.parseClass = function(node, isStatement) {
|
||||
var classBody = this.startNode()
|
||||
classBody.body = []
|
||||
this.expect(tt.braceL)
|
||||
let decorators = []
|
||||
while (!this.eat(tt.braceR)) {
|
||||
if (this.eat(tt.semi)) continue
|
||||
if (this.type === tt.at) {
|
||||
this.decorators.push(this.parseDecorator())
|
||||
decorators.push(this.parseDecorator())
|
||||
continue
|
||||
}
|
||||
var method = this.startNode()
|
||||
this.takeDecorators(method)
|
||||
if (decorators.length) {
|
||||
method.decorators = decorators
|
||||
decorators = []
|
||||
}
|
||||
var isGenerator = this.eat(tt.star), isAsync = false
|
||||
this.parsePropertyName(method)
|
||||
if (this.type !== tt.parenL && !method.computed && method.key.type === "Identifier" &&
|
||||
@@ -517,7 +521,7 @@ pp.parseClass = function(node, isStatement) {
|
||||
}
|
||||
this.parseClassMethod(classBody, method, isGenerator, isAsync)
|
||||
}
|
||||
if (this.decorators.length) {
|
||||
if (decorators.length) {
|
||||
this.raise(this.start, "You have trailing decorators with no method");
|
||||
}
|
||||
node.body = this.finishNode(classBody, "ClassBody")
|
||||
|
||||
@@ -2461,6 +2461,166 @@ test("class Foo { @foo @bar bar() {} }", {
|
||||
features: { "es7.decorators": true }
|
||||
});
|
||||
|
||||
test('@foo({ @bar foo: "bar" }) @bar class Foo {}', {
|
||||
"start": 0,
|
||||
"body": [{
|
||||
"start": 31,
|
||||
"decorators": [{
|
||||
"start": 0,
|
||||
"expression": {
|
||||
"start": 1,
|
||||
"callee": {
|
||||
"start": 1,
|
||||
"name": "foo",
|
||||
"type": "Identifier",
|
||||
"end": 4
|
||||
},
|
||||
"arguments": [{
|
||||
"start": 5,
|
||||
"properties": [{
|
||||
"start": 12,
|
||||
"decorators": [{
|
||||
"start": 7,
|
||||
"expression": {
|
||||
"start": 8,
|
||||
"name": "bar",
|
||||
"type": "Identifier",
|
||||
"end": 11
|
||||
},
|
||||
"type": "Decorator",
|
||||
"end": 11
|
||||
}],
|
||||
"method": false,
|
||||
"shorthand": false,
|
||||
"computed": false,
|
||||
"key": {
|
||||
"start": 12,
|
||||
"name": "foo",
|
||||
"type": "Identifier",
|
||||
"end": 15
|
||||
},
|
||||
"value": {
|
||||
"start": 17,
|
||||
"value": "bar",
|
||||
"raw": "\"bar\"",
|
||||
"type": "Literal",
|
||||
"end": 22
|
||||
},
|
||||
"kind": "init",
|
||||
"type": "Property",
|
||||
"end": 22
|
||||
}],
|
||||
"type": "ObjectExpression",
|
||||
"end": 24
|
||||
}],
|
||||
"type": "CallExpression",
|
||||
"end": 25
|
||||
},
|
||||
"type": "Decorator",
|
||||
"end": 25
|
||||
},
|
||||
{
|
||||
"start": 26,
|
||||
"expression": {
|
||||
"start": 27,
|
||||
"name": "bar",
|
||||
"type": "Identifier",
|
||||
"end": 30
|
||||
},
|
||||
"type": "Decorator",
|
||||
"end": 30
|
||||
}],
|
||||
"id": {
|
||||
"start": 37,
|
||||
"name": "Foo",
|
||||
"type": "Identifier",
|
||||
"end": 40
|
||||
},
|
||||
"superClass": null,
|
||||
"body": {
|
||||
"start": 41,
|
||||
"body": [],
|
||||
"type": "ClassBody",
|
||||
"end": 43
|
||||
},
|
||||
"type": "ClassDeclaration",
|
||||
"end": 43
|
||||
}],
|
||||
"sourceType": "script",
|
||||
"type": "Program",
|
||||
"end": 43
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
features: { "es7.decorators": true }
|
||||
});
|
||||
|
||||
test('@bar class Foo extends @foo class Bar {} {}', {
|
||||
"start": 0,
|
||||
"body": [{
|
||||
"start": 5,
|
||||
"decorators": [{
|
||||
"start": 0,
|
||||
"expression": {
|
||||
"start": 1,
|
||||
"name": "bar",
|
||||
"type": "Identifier",
|
||||
"end": 4
|
||||
},
|
||||
"type": "Decorator",
|
||||
"end": 4
|
||||
}],
|
||||
"id": {
|
||||
"start": 11,
|
||||
"name": "Foo",
|
||||
"type": "Identifier",
|
||||
"end": 14
|
||||
},
|
||||
"superClass": {
|
||||
"start": 28,
|
||||
"decorators": [{
|
||||
"start": 23,
|
||||
"expression": {
|
||||
"start": 24,
|
||||
"name": "foo",
|
||||
"type": "Identifier",
|
||||
"end": 27
|
||||
},
|
||||
"type": "Decorator",
|
||||
"end": 27
|
||||
}],
|
||||
"id": {
|
||||
"start": 34,
|
||||
"name": "Bar",
|
||||
"type": "Identifier",
|
||||
"end": 37
|
||||
},
|
||||
"superClass": null,
|
||||
"body": {
|
||||
"start": 38,
|
||||
"body": [],
|
||||
"type": "ClassBody",
|
||||
"end": 40
|
||||
},
|
||||
"type": "ClassExpression",
|
||||
"end": 40
|
||||
},
|
||||
"body": {
|
||||
"start": 41,
|
||||
"body": [],
|
||||
"type": "ClassBody",
|
||||
"end": 43
|
||||
},
|
||||
"type": "ClassDeclaration",
|
||||
"end": 43
|
||||
}],
|
||||
"sourceType": "script",
|
||||
"type": "Program",
|
||||
"end": 43
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
features: { "es7.decorators": true }
|
||||
});
|
||||
|
||||
testFail("@foo function bar() {}", "Leading decorators must be attached to a class declaration (1:5)", {
|
||||
ecmaVersion: 6,
|
||||
features: { "es7.decorators": true }
|
||||
|
||||
Reference in New Issue
Block a user