Skip to content

Commit

Permalink
Fix: generator methods in classes (fixes #85)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamund Ferguson committed Mar 10, 2015
1 parent 7e064fe commit 9eac2ef
Show file tree
Hide file tree
Showing 19 changed files with 434 additions and 22 deletions.
80 changes: 58 additions & 22 deletions espree.js
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ function parseJSXElement() {
* Applies location information to the given node by using the given marker.
* The marker indicates the point at which the node is said to have to begun
* in the source code.
* @param {Object} marker The market to use for the node.
* @param {Object} marker The marker to use for the node.
* @param {ASTNode} node The AST node to apply location information to.
* @returns {ASTNode} The node that was passed in.
* @private
Expand Down Expand Up @@ -2451,6 +2451,33 @@ function tryParseMethodDefinition(token, key, computed, marker) {
return null;
}

/**
* Parses Generator Properties
* @param {ASTNode} key The property key (usually an identifier).
* @param {Object} marker The marker to use for the node.
* @returns {ASTNode} The generator property node.
*/
function parseGeneratorProperty(key, marker) {

var computed = (lookahead.type === Token.Punctuator && lookahead.value === "[");

if (!match("(")) {
throwUnexpected(lex());
}

return markerApply(
marker,
astNodeFactory.createProperty(
"init",
key,
parsePropertyMethodFunction({ generator: true }),
true,
false,
computed
)
);
}

// TODO(nzakas): Update to match Esprima
function parseObjectProperty() {
var token, key, id, computed, methodMarker, options;
Expand Down Expand Up @@ -2610,32 +2637,17 @@ function parseObjectProperty() {
);
}

// only possibility in this branch is a generator
// only possibility in this branch is a shorthand generator
if (token.type === Token.EOF || token.type === Token.Punctuator) {
if (!allowGenerators || !match("*")) {
if (!allowGenerators || !match("*") || !allowMethod) {
throwUnexpected(token);
}
lex();

computed = (lookahead.type === Token.Punctuator && lookahead.value === "[");
lex();

id = parseObjectPropertyKey();

if (!match("(")) {
throwUnexpected(lex());
}

return markerApply(
marker,
astNodeFactory.createProperty(
"init",
id,
parsePropertyMethodFunction({ generator: true }),
true,
false,
computed
)
);
return parseGeneratorProperty(id, marker);

}

Expand Down Expand Up @@ -4908,7 +4920,9 @@ function parseImportDeclaration() {
// 14.5 Class Definitions

function parseClassBody() {
var token, isStatic, hasConstructor = false, body = [], method, computed, key;
var hasConstructor = false, generator = false,
allowGenerators = extra.ecmaFeatures.generators,
token, isStatic, body = [], method, computed, key;

var existingProps = {},
topMarker = markerCreate(),
Expand All @@ -4929,18 +4943,40 @@ function parseClassBody() {

token = lookahead;
isStatic = false;
generator = match("*");
computed = match("[");
marker = markerCreate();

if (generator) {
if (!allowGenerators) {
throwUnexpected(lookahead);
}
lex();
}

key = parseObjectPropertyKey();

// static generator methods
if (key.name === "static" && match("*")) {
if (!allowGenerators) {
throwUnexpected(lookahead);
}
generator = true;
lex();
}

if (key.name === "static" && lookaheadPropertyName()) {
token = lookahead;
isStatic = true;
computed = match("[");
key = parseObjectPropertyKey();
}

method = tryParseMethodDefinition(token, key, computed, marker);
if (generator) {
method = parseGeneratorProperty(key, marker);
} else {
method = tryParseMethodDefinition(token, key, computed, marker, generator);
}

if (method) {
method.static = isStatic;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
classes: true,
generators: true
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
module.exports = {
"type": "Program",
"body": [
{
"type": "ClassDeclaration",
"id": {
"type": "Identifier",
"name": "Foo",
"range": [
6,
9
],
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 9
}
}
},
"superClass": null,
"body": {
"type": "ClassBody",
"body": [
{
"type": "MethodDefinition",
"key": {
"type": "Identifier",
"name": "bar",
"range": [
14,
17
],
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 5
}
}
},
"value": {
"type": "FunctionExpression",
"id": null,
"params": [],
"defaults": [],
"body": {
"type": "BlockStatement",
"body": [],
"range": [
20,
24
],
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 3,
"column": 2
}
}
},
"rest": null,
"generator": true,
"expression": false,
"range": [
17,
24
],
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 3,
"column": 2
}
}
},
"kind": "method",
"computed": false,
"range": [
13,
24
],
"loc": {
"start": {
"line": 2,
"column": 1
},
"end": {
"line": 3,
"column": 2
}
},
"static": false
}
],
"range": [
10,
26
],
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 4,
"column": 1
}
}
},
"range": [
0,
26
],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
}
}
],
"range": [
0,
26
],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 4,
"column": 1
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Foo {
*bar() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
classes: true,
generators: false
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
"index": 16,
"lineNumber": 2,
"column": 5,
"description": "Unexpected token *"
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Foo {
*bar() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
classes: false,
objectLiteralShorthandMethods: false,
generators: false
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
"index": 0,
"lineNumber": 1,
"column": 1,
"description": "Unexpected reserved word"
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Foo {
*bar() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
classes: true,
generators: false
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
"index": 20,
"lineNumber": 2,
"column": 9,
"description": "Unexpected token *"
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Foo {
static *bar() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
classes: true,
generators: true
};
Loading

0 comments on commit 9eac2ef

Please sign in to comment.