diff --git a/README.md b/README.md index 245b71bccd..32ee0b7d76 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,9 @@ object referring to that same position. trailing commas in array and object literals. Default is `true`. - **forbidReserved**: If `true`, using a reserved word will generate - an error. Defaults to `false`. + an error. Defaults to `false`. When given the value `"everywhere"`, + reserved words and keywords can also not be used as property names + (as in Internet Explorer's old parser). - **allowReturnOutsideFunction**: By default, a return statement at the top level raises an error. Set this to `true` to accept such diff --git a/acorn.js b/acorn.js index b58f1dab92..0f11931752 100644 --- a/acorn.js +++ b/acorn.js @@ -62,7 +62,9 @@ // trailing commas in array and object literals. allowTrailingCommas: true, // By default, reserved words are not enforced. Enable - // `forbidReserved` to enforce them. + // `forbidReserved` to enforce them. When this option has the + // value "everywhere", reserved words and keywords can also not be + // used as property names. forbidReserved: false, // When enabled, a return at the top level is not considered an // error. @@ -941,13 +943,8 @@ function readWord() { var word = readWord1(); var type = _name; - if (!containsEsc) { - if (isKeyword(word)) type = keywordTypes[word]; - else if (options.forbidReserved && - (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(word) || - strict && isStrictReservedWord(word)) - raise(tokStart, "The keyword '" + word + "' is reserved"); - } + if (!containsEsc && isKeyword(word)) + type = keywordTypes[word]; return finishToken(type, word); } @@ -1763,7 +1760,20 @@ function parseIdent(liberal) { var node = startNode(); - node.name = tokType === _name ? tokVal : (liberal && !options.forbidReserved && tokType.keyword) || unexpected(); + if (liberal && options.forbidReserved == "everywhere") liberal = false; + if (tokType === _name) { + if (!liberal && + (options.forbidReserved && + (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(tokVal) || + strict && isStrictReservedWord(tokVal)) && + input.slice(tokStart, tokEnd).indexOf("\\") == -1) + raise(tokStart, "The keyword '" + tokVal + "' is reserved"); + node.name = tokVal; + } else if (liberal && tokType.keyword) { + node.name = tokType.keyword; + } else { + unexpected(); + } tokRegexpAllowed = false; next(); return finishNode(node, "Identifier"); diff --git a/index.html b/index.html index 74e39e6a5b..f189721410 100644 --- a/index.html +++ b/index.html @@ -39,7 +39,9 @@ influences support for strict mode, the set of reserved words, and support for getters and setter.
ecmaVersion: 5,Turn on strictSemicolons to prevent the parser from doing
automatic semicolon insertion.
strictSemicolons: false,When allowTrailingCommas is false, the parser will not allow
trailing commas in array and object literals.
allowTrailingCommas: true,By default, reserved words are not enforced. Enable
-forbidReserved to enforce them.
forbidReserved: false,When enabled, a return at the top level is not considered an
+forbidReserved to enforce them. When this option has the
+value "everywhere", reserved words and keywords can also not be
+used as property names.
forbidReserved: false,When enabled, a return at the top level is not considered an error.
allowReturnOutsideFunction: false,When locations is on, loc properties holding objects with
start and end properties in {line, column} form (with
line being 1-based and column 0-based) will be attached to the
@@ -676,13 +678,8 @@ containeds an escape, as a micro-optimization.
function readWord() {
var word = readWord1();
var type = _name;
- if (!containsEsc) {
- if (isKeyword(word)) type = keywordTypes[word];
- else if (options.forbidReserved &&
- (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(word) ||
- strict && isStrictReservedWord(word))
- raise(tokStart, "The keyword '" + word + "' is reserved");
- }
+ if (!containsEsc && isKeyword(word))
+ type = keywordTypes[word];
return finishToken(type, word);
}A recursive descent parser operates by defining functions for all syntactic elements, and recursively calling those, each function @@ -1323,7 +1320,20 @@ for array literals).
function parseIdent(liberal) {
var node = startNode();
- node.name = tokType === _name ? tokVal : (liberal && !options.forbidReserved && tokType.keyword) || unexpected();
+ if (liberal && options.forbidReserved == "everywhere") liberal = false;
+ if (tokType === _name) {
+ if (!liberal &&
+ (options.forbidReserved &&
+ (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(tokVal) ||
+ strict && isStrictReservedWord(tokVal)) &&
+ input.slice(tokStart, tokEnd).indexOf("\\") == -1)
+ raise(tokStart, "The keyword '" + tokVal + "' is reserved");
+ node.name = tokVal;
+ } else if (liberal && tokType.keyword) {
+ node.name = tokType.keyword;
+ } else {
+ unexpected();
+ }
tokRegexpAllowed = false;
next();
return finishNode(node, "Identifier");
diff --git a/test/tests.js b/test/tests.js
index efce0b4122..9cb04321fb 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -26348,6 +26348,39 @@ test("x = y-->10;\n --> nothing", {
]
});
+test("'use strict';\nobject.static();", {
+ type: "Program",
+ body: [
+ {
+ type: "ExpressionStatement",
+ expression: {
+ type: "Literal",
+ value: "use strict",
+ raw: "'use strict'"
+ }
+ },
+ {
+ type: "ExpressionStatement",
+ expression: {
+ type: "CallExpression",
+ callee: {
+ type: "MemberExpression",
+ object: {
+ type: "Identifier",
+ name: "object"
+ },
+ property: {
+ type: "Identifier",
+ name: "static"
+ },
+ computed: false
+ },
+ arguments: []
+ }
+ }
+ ]
+});
+
// Failure tests
testFail("{",