[Pkg-javascript-commits] [node-acorn-jsx] 213/484: Added ES6 classes support.
Bastien Roucariès
rouca at moszumanska.debian.org
Sat Aug 19 14:20:30 UTC 2017
This is an automated email from the git hooks/post-receive script.
rouca pushed a commit to branch master
in repository node-acorn-jsx.
commit 44a4f8c01608b11daa8964dd7240034b78f8e90a
Author: Ingvar Stepanyan <me at rreverser.com>
Date: Thu Jul 24 15:48:48 2014 +0300
Added ES6 classes support.
---
acorn.js | 86 ++++++++++++++++++++++++++++++++++++++-------------
test/tests-harmony.js | 38 +++++++++++------------
2 files changed, 83 insertions(+), 41 deletions(-)
diff --git a/acorn.js b/acorn.js
index da572a8..aa7b519 100644
--- a/acorn.js
+++ b/acorn.js
@@ -281,6 +281,7 @@
var _let = {keyword: "let"}, _const = {keyword: "const"};
var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};
var _this = {keyword: "this"};
+ var _class = {keyword: "class"}, _extends = {keyword: "extends", beforeExpr: true}, _static = {keyword: "static"};
// The keywords that denote values.
@@ -305,7 +306,8 @@
"instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this,
"typeof": {keyword: "typeof", prefix: true, beforeExpr: true},
"void": {keyword: "void", prefix: true, beforeExpr: true},
- "delete": {keyword: "delete", prefix: true, beforeExpr: true}};
+ "delete": {keyword: "delete", prefix: true, beforeExpr: true},
+ "class": _class, "extends": _extends, "static": _static};
// Punctuation token types. Again, the `type` property is purely for debugging.
@@ -424,7 +426,7 @@
var isEcma5AndLessKeyword = makePredicate(ecma5AndLessKeywords);
- var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const");
+ var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends static");
var isKeyword = isEcma5AndLessKeyword;
@@ -1217,6 +1219,7 @@
case _do: return parseDoStatement(node);
case _for: return parseForStatement(node);
case _function: return parseFunctionStatement(node);
+ case _class: return parseClass(node, true);
case _if: return parseIfStatement(node);
case _return: return parseReturnStatement(node);
case _switch: return parseSwitchStatement(node);
@@ -1731,6 +1734,9 @@
next();
return parseFunction(node, false);
+ case _class:
+ return parseClass(startNode(), false);
+
case _new:
return parseNew();
@@ -1776,7 +1782,7 @@
if (options.allowTrailingCommas && eat(_braceR)) break;
} else first = false;
- var prop = startNode(), isGetSet = false, kind;
+ var prop = startNode(), kind;
prop.key = parsePropertyName();
if (options.ecmaVersion >= 6) {
prop.method = false;
@@ -1794,7 +1800,7 @@
prop.value = func;
} else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
(prop.key.name === "get" || prop.key.name === "set")) {
- isGetSet = sawGetSet = true;
+ sawGetSet = true;
kind = prop.kind = prop.key.name;
prop.key = parsePropertyName();
if (tokType !== _parenL) unexpected();
@@ -1805,24 +1811,30 @@
prop.value = func;
} else unexpected();
- // getters and setters are not allowed to clash — either with
- // each other or with an init property — and in strict mode,
- // init properties are also not allowed to be repeated.
-
- if (prop.key.type === "Identifier" && (strict || sawGetSet)) {
- for (var i = 0; i < node.properties.length; ++i) {
- var other = node.properties[i];
- if (other.key.name === prop.key.name) {
- var conflict = kind == other.kind || isGetSet && other.kind === "init" ||
- kind === "init" && (other.kind === "get" || other.kind === "set");
- if (conflict && !strict && kind === "init" && other.kind === "init") conflict = false;
- if (conflict) raise(prop.key.start, "Redefinition of property");
- }
+ addProperty(node.properties, finishNode(prop, "Property"), sawGetSet, "init");
+ }
+ return finishNode(node, "ObjectExpression");
+ }
+
+ // Add property to list with keeping in mind and checking that
+ // object/class getters and setters are not allowed to clash —
+ // either with each other or with an init property — and in
+ // strict mode, init properties are also not allowed to be repeated.
+
+ function addProperty(props, current, sawGetSet, defaultKind) {
+ if (current.key.type === "Identifier" && (strict || sawGetSet)) {
+ var kind = current.kind, isGetSet = kind !== defaultKind;
+ for (var i = 0; i < props.length; ++i) {
+ var other = props[i];
+ if (other.key.name === current.key.name && other.static === current.static) {
+ var conflict = kind == other.kind || isGetSet && other.kind === defaultKind ||
+ kind === defaultKind && (other.kind !== defaultKind);
+ if (conflict && !strict && kind === defaultKind && other.kind === defaultKind) conflict = false;
+ if (conflict) raise(current.key.start, "Redefinition of property");
}
}
- node.properties.push(finishNode(prop, "Property"));
}
- return finishNode(node, "ObjectExpression");
+ props.push(current);
}
function parsePropertyName() {
@@ -1830,8 +1842,7 @@
return parseIdent(true);
}
- // Parse a function declaration or literal (depending on the
- // `isStatement` parameter).
+ // Initialize empty function node with given name.
function initFunction(node, id) {
node.id = id || null;
@@ -1844,6 +1855,9 @@
return node;
}
+ // Parse a function declaration or literal (depending on the
+ // `isStatement` parameter).
+
function parseFunction(node, isStatement, allowExpression) {
initFunction(node, tokType === _name ? parseIdent() : isStatement ? unexpected() : null);
parseFunctionParams(node);
@@ -1946,6 +1960,36 @@
}
}
+ // Parse a class declaration or literal (depending on the
+ // `isStatement` parameter).
+
+ function parseClass(node, isStatement) {
+ next();
+ node.id = tokType === _name ? parseIdent() : isStatement ? unexpected() : null;
+ node.superClass = eat(_extends) ? parseExpression() : null;
+ var classBody = startNode(), sawGetSet = false;
+ classBody.body = [];
+ expect(_braceL);
+ while (!eat(_braceR)) {
+ var method = startNode();
+ method.static = !!eat(_static);
+ method.key = parseIdent(true);
+ if (method.key.type === "Identifier" && (method.key.name === "get" || method.key.name === "set") && tokType === _name) {
+ method.kind = method.key.name;
+ method.key = parseIdent(true);
+ sawGetSet = true;
+ } else {
+ method.kind = "";
+ }
+ method.value = parseFunction(startNode());
+ setLoc(method.value, method.value.body);
+ addProperty(classBody.body, finishNode(method, "MethodDefinition"), sawGetSet, "");
+ eat(_semi);
+ }
+ node.body = finishNode(classBody, "ClassBody");
+ return finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
+ }
+
// Parses a comma-separated list of expressions, and returns them as
// an array. `close` is the token type that ends the list, and
// `allowEmpty` can be turned on to allow subsequent commas with
diff --git a/test/tests-harmony.js b/test/tests-harmony.js
index cc9e13d..e18edad 100644
--- a/test/tests-harmony.js
+++ b/test/tests-harmony.js
@@ -9205,10 +9205,10 @@ test("\"use strict\"; (class A {constructor() { super() }})", {
end: {line: 1, column: 47}
}
},
- range: [40, 48],
+ range: [40, 47],
loc: {
start: {line: 1, column: 40},
- end: {line: 1, column: 48}
+ end: {line: 1, column: 47}
}
}],
range: [38, 49],
@@ -9240,10 +9240,10 @@ test("\"use strict\"; (class A {constructor() { super() }})", {
end: {line: 1, column: 50}
}
},
- range: [15, 50],
+ range: [14, 51],
loc: {
- start: {line: 1, column: 15},
- end: {line: 1, column: 50}
+ start: {line: 1, column: 14},
+ end: {line: 1, column: 51}
}
},
range: [14, 51],
@@ -9257,8 +9257,7 @@ test("\"use strict\"; (class A {constructor() { super() }})", {
loc: {
start: {line: 1, column: 0},
end: {line: 1, column: 51}
- },
- comments: []
+ }
}, {
ecmaVersion: 6,
ranges: true,
@@ -9546,10 +9545,10 @@ test("\"use strict\"; (class A { static constructor() { super() }})", {
end: {line: 1, column: 55}
}
},
- range: [48, 56],
+ range: [48, 55],
loc: {
start: {line: 1, column: 48},
- end: {line: 1, column: 56}
+ end: {line: 1, column: 55}
}
}],
range: [46, 57],
@@ -9581,10 +9580,10 @@ test("\"use strict\"; (class A { static constructor() { super() }})", {
end: {line: 1, column: 58}
}
},
- range: [15, 58],
+ range: [14, 59],
loc: {
- start: {line: 1, column: 15},
- end: {line: 1, column: 58}
+ start: {line: 1, column: 14},
+ end: {line: 1, column: 59}
}
},
range: [14, 59],
@@ -9598,8 +9597,7 @@ test("\"use strict\"; (class A { static constructor() { super() }})", {
loc: {
start: {line: 1, column: 0},
end: {line: 1, column: 59}
- },
- comments: []
+ }
}, {
ecmaVersion: 6,
ranges: true,
@@ -10472,17 +10470,17 @@ test("class A { set foo(v) {} get foo() {} }", {
locations: true
});
-testFail("class A { get foo() {} get foo() {} }", "Unexpected token (1:31)", {ecmaVersion: 6});
+testFail("class A { get foo() {} get foo() {} }", "Redefinition of property (1:27)", {ecmaVersion: 6});
-testFail("class A { set foo(v) {} set foo(v) {} }", "Unexpected token (1:32)", {ecmaVersion: 6});
+testFail("class A { set foo(v) {} set foo(v) {} }", "Redefinition of property (1:28)", {ecmaVersion: 6});
-testFail("class A { get foo() {} foo() {} }", "Unexpected token (1:27)", {ecmaVersion: 6});
+testFail("class A { get foo() {} foo() {} }", "Redefinition of property (1:23)", {ecmaVersion: 6});
-testFail("class A { foo() {} get foo() {} }", "Unexpected token (1:27)", {ecmaVersion: 6});
+testFail("class A { foo() {} get foo() {} }", "Redefinition of property (1:23)", {ecmaVersion: 6});
-testFail("class A { set foo(v) {} foo() {} }", "Unexpected token (1:28)", {ecmaVersion: 6});
+testFail("class A { set foo(v) {} foo() {} }", "Redefinition of property (1:24)", {ecmaVersion: 6});
-testFail("class A { foo() {} set foo(v) {} }", "Unexpected token (1:27)", {ecmaVersion: 6});
+testFail("class A { foo() {} set foo(v) {} }", "Redefinition of property (1:23)", {ecmaVersion: 6});
// ES6: Computed Properties
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-acorn-jsx.git
More information about the Pkg-javascript-commits
mailing list