test262: test262/test/language/expressions/generators/yield-as-label.js
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Apr 2017 16:06:33 +0000 (16:06 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Apr 2017 16:06:33 +0000 (16:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170979

Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-04-24
Reviewed by Saam Barati.

JSTests:

* stress/async-await-module-reserved-word.js:
* stress/async-await-reserved-word.js:
Converge on "Cannot" instead of "Can't".

* catch-parameter-syntax.js:
* yield-named-variable-generator.js:
* yield-named-variable.js:
* stress/yield-label-generator.js:
* stress/yield-label.js:
* stress/yield-reserved-word.js: Added.
More complete list of when 'yield' is allowed.

* ChakraCore/test/strict/23.reservedWords_sm.baseline-jsc:
* test262.yaml:

Source/JavaScriptCore:

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseVariableDeclarationList):
(JSC::Parser<LexerType>::parseDestructuringPattern):
(JSC::Parser<LexerType>::parseFormalParameters):
Converge on "Cannot" instead of "Can't" in error messages.

(JSC::Parser<LexerType>::parseFunctionInfo):
Disallow "yield" as the generator function name in function expressions.
This refers to the difference between Declaration and Expression, where
only GeneratorExpression explicitly has [+Yield] disallowing yield for
the generator name:

    GeneratorDeclaration[Yield, Await, Default]:
        function * BindingIdentifier[?Yield, ?Await] ...

    GeneratorExpression:
        function * BindingIdentifier[+Yield, ~Await]opt ...

(JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
Disallow "yield" as a label name in strict mode or inside a generator.

(JSC::Parser<LexerType>::parseProperty):
Disallow "yield" or any keyword in object literal shorthands.

* parser/Parser.h:
(JSC::Parser::getToken):
(JSC::Parser::isDisallowedIdentifierLet):
(JSC::Parser::isDisallowedIdentifierYield):
(JSC::Parser::disallowedIdentifierLetReason):
(JSC::Parser::disallowedIdentifierYieldReason):
Follow pattern for improved error messages based on context.

LayoutTests:

* js/object-literal-shorthand-construction-expected.txt:
* js/script-tests/object-literal-shorthand-construction.js:
Extend this test to cover object literal shorthand with keywords.

* js/dom/reserved-words-as-property-expected.txt:
* js/let-syntax-expected.txt:
* js/parser-syntax-check-expected.txt:
Improved error messages.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215682 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
JSTests/ChakraCore/test/strict/23.reservedWords_sm.baseline-jsc
JSTests/ChangeLog
JSTests/stress/async-await-module-reserved-word.js
JSTests/stress/async-await-reserved-word.js
JSTests/stress/catch-parameter-syntax.js
JSTests/stress/yield-label-generator.js
JSTests/stress/yield-label.js
JSTests/stress/yield-named-variable-generator.js
JSTests/stress/yield-named-variable.js
JSTests/stress/yield-reserved-word.js [new file with mode: 0644]
JSTests/test262.yaml
LayoutTests/ChangeLog
LayoutTests/js/dom/reserved-words-as-property-expected.txt
LayoutTests/js/let-syntax-expected.txt
LayoutTests/js/object-literal-shorthand-construction-expected.txt
LayoutTests/js/parser-syntax-check-expected.txt
LayoutTests/js/script-tests/object-literal-shorthand-construction.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h

index c1e53c4..d45fb3e 100644 (file)
@@ -75,7 +75,7 @@ SyntaxError: Cannot use the reserved word 'implements' as a variable name in str
 (function(){var interface;})();
 SyntaxError: Cannot use the reserved word 'interface' as a variable name in strict mode.
 (function(){var let;})();
-SyntaxError: Cannot use the keyword 'let' as a variable name.
+SyntaxError: Cannot use 'let' as a variable name in strict mode.
 (function(){var package;})();
 SyntaxError: Cannot use the reserved word 'package' as a variable name in strict mode.
 (function(){var private;})();
@@ -87,7 +87,7 @@ SyntaxError: Cannot use the reserved word 'public' as a variable name in strict
 (function(){var static;})();
 SyntaxError: Cannot use the reserved word 'static' as a variable name in strict mode.
 (function(){var yield;})();
-SyntaxError: Cannot use the keyword 'yield' as a variable name.
+SyntaxError: Cannot use 'yield' as a variable name in strict mode.
 (function(){var foo;})();
 (function(){var <;})();
 SyntaxError: Unexpected token '<'. Expected a parameter pattern or a ')' in parameter list.
@@ -168,7 +168,7 @@ SyntaxError: Cannot use the reserved word 'implements' as a function name in str
 (function(){function interface(){}})();
 SyntaxError: Cannot use the reserved word 'interface' as a function name in strict mode.
 (function(){function let(){}})();
-SyntaxError: Cannot use the keyword 'let' as a function name.
+SyntaxError: Cannot use 'let' as a function name in strict mode.
 (function(){function package(){}})();
 SyntaxError: Cannot use the reserved word 'package' as a function name in strict mode.
 (function(){function private(){}})();
@@ -180,7 +180,7 @@ SyntaxError: Cannot use the reserved word 'public' as a function name in strict
 (function(){function static(){}})();
 SyntaxError: Cannot use the reserved word 'static' as a function name in strict mode.
 (function(){function yield(){}})();
-SyntaxError: Cannot use the keyword 'yield' as a function name.
+SyntaxError: Cannot use 'yield' as a function name in strict mode.
 (function(){function foo(){}})();
 (function(){function <(){}})();
 SyntaxError: Unexpected token '<'
@@ -261,7 +261,7 @@ SyntaxError: Cannot use the reserved word 'implements' as a function name in str
 (function(){(function interface(){})})();
 SyntaxError: Cannot use the reserved word 'interface' as a function name in strict mode.
 (function(){(function let(){})})();
-SyntaxError: Cannot use the keyword 'let' as a function name.
+SyntaxError: Cannot use 'let' as a function name in strict mode.
 (function(){(function package(){})})();
 SyntaxError: Cannot use the reserved word 'package' as a function name in strict mode.
 (function(){(function private(){})})();
@@ -273,7 +273,7 @@ SyntaxError: Cannot use the reserved word 'public' as a function name in strict
 (function(){(function static(){})})();
 SyntaxError: Cannot use the reserved word 'static' as a function name in strict mode.
 (function(){(function yield(){})})();
-SyntaxError: Cannot use the keyword 'yield' as a function name.
+SyntaxError: Cannot use 'yield' as a function name in strict mode.
 (function(){(function foo(){})})();
 (function(){(function <(){})})();
 SyntaxError: Unexpected token '<'. Expected an opening '(' before a function's parameter list.
@@ -354,7 +354,7 @@ SyntaxError: Cannot use the reserved word 'implements' as a parameter name in st
 (function(){(function(interface){});})();
 SyntaxError: Cannot use the reserved word 'interface' as a parameter name in strict mode.
 (function(){(function(let){});})();
-SyntaxError: Cannot use the keyword 'let' as a parameter name.
+SyntaxError: Cannot use 'let' as a parameter name in strict mode.
 (function(){(function(package){});})();
 SyntaxError: Cannot use the reserved word 'package' as a parameter name in strict mode.
 (function(){(function(private){});})();
@@ -366,7 +366,7 @@ SyntaxError: Cannot use the reserved word 'public' as a parameter name in strict
 (function(){(function(static){});})();
 SyntaxError: Cannot use the reserved word 'static' as a parameter name in strict mode.
 (function(){(function(yield){});})();
-SyntaxError: Cannot use the keyword 'yield' as a parameter name.
+SyntaxError: Cannot use 'yield' as a parameter name in strict mode.
 (function(){(function(foo){});})();
 (function(){(function(<){});})();
 SyntaxError: Unexpected token '<'. Expected a parameter pattern or a ')' in parameter list.
@@ -447,7 +447,7 @@ SyntaxError: Cannot use the reserved word 'implements' as a catch parameter name
 (function(){try{} catch(interface){}})();
 SyntaxError: Cannot use the reserved word 'interface' as a catch parameter name in strict mode.
 (function(){try{} catch(let){}})();
-SyntaxError: Cannot use the keyword 'let' as a catch parameter name.
+SyntaxError: Cannot use 'let' as a catch parameter name in strict mode.
 (function(){try{} catch(package){}})();
 SyntaxError: Cannot use the reserved word 'package' as a catch parameter name in strict mode.
 (function(){try{} catch(private){}})();
@@ -459,7 +459,7 @@ SyntaxError: Cannot use the reserved word 'public' as a catch parameter name in
 (function(){try{} catch(static){}})();
 SyntaxError: Cannot use the reserved word 'static' as a catch parameter name in strict mode.
 (function(){try{} catch(yield){}})();
-SyntaxError: Cannot use the keyword 'yield' as a catch parameter name.
+SyntaxError: Cannot use 'yield' as a catch parameter name in strict mode.
 (function(){try{} catch(foo){}})();
 (function(){try{} catch(<){}})();
 SyntaxError: Unexpected token '<'. Expected a parameter pattern or a ')' in parameter list.
index 89c76d8..ab3075b 100644 (file)
@@ -1,3 +1,25 @@
+2017-04-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        test262: test262/test/language/expressions/generators/yield-as-label.js
+        https://bugs.webkit.org/show_bug.cgi?id=170979
+
+        Reviewed by Saam Barati.
+
+        * stress/async-await-module-reserved-word.js:
+        * stress/async-await-reserved-word.js:
+        Converge on "Cannot" instead of "Can't".
+
+        * catch-parameter-syntax.js:
+        * yield-named-variable-generator.js:
+        * yield-named-variable.js:
+        * stress/yield-label-generator.js:
+        * stress/yield-label.js:
+        * stress/yield-reserved-word.js: Added.
+        More complete list of when 'yield' is allowed.
+
+        * ChakraCore/test/strict/23.reservedWords_sm.baseline-jsc:
+        * test262.yaml:
+
 2017-04-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r215674.
index eb2562c..f8671b8 100644 (file)
@@ -19,22 +19,22 @@ function checkModuleSyntaxError(source, errorMessage) {
 
 checkModuleSyntaxError(String.raw`
 var await;
-`, `SyntaxError: Can't use 'await' as a variable name in a module.:2`);
+`, `SyntaxError: Cannot use 'await' as a variable name in a module.:2`);
 checkModuleSyntaxError(`
 export var await;
-`, `SyntaxError: Can't use 'await' as a variable name in a module.:2`);
+`, `SyntaxError: Cannot use 'await' as a variable name in a module.:2`);
 checkModuleSyntaxError(String.raw`
 let await;
-`, `SyntaxError: Can't use 'await' as a lexical variable name in a module.:2`);
+`, `SyntaxError: Cannot use 'await' as a lexical variable name in a module.:2`);
 checkModuleSyntaxError(String.raw`
 export let await;
-`, `SyntaxError: Can't use 'await' as a lexical variable name in a module.:2`);
+`, `SyntaxError: Cannot use 'await' as a lexical variable name in a module.:2`);
 checkModuleSyntaxError(String.raw`
 const await = 1
-`, `SyntaxError: Can't use 'await' as a lexical variable name in a module.:2`);
+`, `SyntaxError: Cannot use 'await' as a lexical variable name in a module.:2`);
 checkModuleSyntaxError(String.raw`
 export const await = 1
-`, `SyntaxError: Can't use 'await' as a lexical variable name in a module.:2`);
+`, `SyntaxError: Cannot use 'await' as a lexical variable name in a module.:2`);
 
 checkModuleSyntaxError(String.raw`
 function await() {}
index 9c9f104..415b2bf 100644 (file)
@@ -22,142 +22,142 @@ noInline(shouldThrowSyntaxError);
 var AsyncFunction = (async function() {}).constructor;
 
 // AsyncFunctionExpression
-shouldThrowSyntaxError("(async function() { var await; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("(async function() { var [await] = []; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("(async function() { var [...await] = []; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("(async function() { var {await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("(async function() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("(async function() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("(async function() { let await; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { let [await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { let [...await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { let {await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { let {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { let {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { const await; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { const [await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { const [...await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { const {await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { const {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("(async function() { const {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { var await; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("(async function() { var [await] = []; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("(async function() { var [...await] = []; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("(async function() { var {await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("(async function() { var {isAsync: await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("(async function() { var {isAsync: await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("(async function() { let await; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { let [await] = []; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { let [...await] = []; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { let {await} = {}; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { let {isAsync: await} = {}; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { let {isAsync: await} = {}; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { const await; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { const [await] = []; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { const [...await] = []; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { const {await} = {}; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { const {isAsync: await} = {}; })", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("(async function() { const {isAsync: await} = {}; })", "Cannot use 'await' as a lexical variable name in an async function.");
 shouldThrowSyntaxError("(async function() { function await() {} })", "Cannot declare function named 'await' in an async function.");
 shouldThrowSyntaxError("(async function() { async function await() {} })", "Cannot declare function named 'await' in an async function.");
-shouldThrowSyntaxError("(async function(await) {})", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("(async function f([await]) {})", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("(async function f([...await]) {})", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("(async function f(...await) {})", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("(async function f({await}) {})", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("(async function f({isAsync: await}) {})", "Can't use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("(async function(await) {})", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("(async function f([await]) {})", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("(async function f([...await]) {})", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("(async function f(...await) {})", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("(async function f({await}) {})", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("(async function f({isAsync: await}) {})", "Cannot use 'await' as a parameter name in an async function.");
 
 // AsyncFunctionDeclaration
-shouldThrowSyntaxError("async function f() { var await; }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("async function f() { var [await] = []; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("async function f() { var [...await] = []; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("async function f() { var {await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("async function f() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("async function f() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("async function f() { let await; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { let [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { let [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { let {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { const await; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { const [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { const [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { const {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("async function f() { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { var await; }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("async function f() { var [await] = []; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("async function f() { var [...await] = []; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("async function f() { var {await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("async function f() { var {isAsync: await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("async function f() { var {isAsync: await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("async function f() { let await; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { let [await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { let [...await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { let {await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { let {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { let {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { const await; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { const [await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { const [...await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { const {await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { const {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("async function f() { const {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
 shouldThrowSyntaxError("async function f() { function await() {} }", "Cannot declare function named 'await' in an async function.");
 shouldThrowSyntaxError("async function f() { async function await() {} }", "Cannot declare function named 'await' in an async function.");
-shouldThrowSyntaxError("async function f(await) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("async function f([await]) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("async function f([...await]) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("async function f(...await) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("async function f({await}) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("async function f({isAsync: await}) {}", "Can't use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("async function f(await) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("async function f([await]) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("async function f([...await]) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("async function f(...await) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("async function f({await}) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("async function f({isAsync: await}) {}", "Cannot use 'await' as a parameter name in an async function.");
 
 // AsyncArrowFunction
-shouldThrowSyntaxError("var f = async () => { var await; }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { var [await] = []; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { var [...await] = []; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { var {await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { let await; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { let [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { let [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { let {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { const await; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { const [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { const [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { const {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var f = async () => { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { var await; }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { var [await] = []; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { var [...await] = []; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { var {await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { var {isAsync: await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { var {isAsync: await} = {}; })", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { let await; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { let [await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { let [...await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { let {await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { let {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { let {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { const await; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { const [await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { const [...await] = []; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { const {await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { const {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var f = async () => { const {isAsync: await} = {}; }", "Cannot use 'await' as a lexical variable name in an async function.");
 shouldThrowSyntaxError("var f = async () => { function await() {} }", "Cannot declare function named 'await' in an async function.");
 shouldThrowSyntaxError("var f = async () => { async function await() {} }", "Cannot declare function named 'await' in an async function.");
-shouldThrowSyntaxError("var f = async (await) => {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var f = async ([await]) => {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var f = async ([...await]) => {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var f = async (...await) => {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var f = async ({await}) => {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var f = async ({isAsync: await}) => {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var f = async await => {}", "Can't use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var f = async (await) => {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var f = async ([await]) => {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var f = async ([...await]) => {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var f = async (...await) => {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var f = async ({await}) => {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var f = async ({isAsync: await}) => {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var f = async await => {}", "Cannot use 'await' as a parameter name in an async function.");
 
 // AsyncMethod
-shouldThrowSyntaxError("var O = { async f() { var await; } }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { var [await] = []; } }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { var [...await] = []; } }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { var {await} = {}; } }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { var {isAsync: await} = {}; } }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { var {isAsync: await} = {}; } }", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { let await; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { let [await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { let [...await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { let {await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { let {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { let {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { const await; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { const [await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { const [...await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { const {await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { const {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("var O = { async f() { const {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { var await; } }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { var [await] = []; } }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { var [...await] = []; } }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { var {await} = {}; } }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { var {isAsync: await} = {}; } }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { var {isAsync: await} = {}; } }", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { let await; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { let [await] = []; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { let [...await] = []; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { let {await} = {}; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { let {isAsync: await} = {}; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { let {isAsync: await} = {}; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { const await; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { const [await] = []; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { const [...await] = []; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { const {await} = {}; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { const {isAsync: await} = {}; } }", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("var O = { async f() { const {isAsync: await} = {}; } }", "Cannot use 'await' as a lexical variable name in an async function.");
 shouldThrowSyntaxError("var O = { async f() { function await() {} }", "Cannot declare function named 'await' in an async function.");
 shouldThrowSyntaxError("var O = { async f() { async function await() {} } }", "Cannot declare function named 'await' in an async function.");
-shouldThrowSyntaxError("var O = { async f(await) {} } ", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var O = { async f([await]) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var O = { async f([...await]) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var O = { async f(...await) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var O = { async f({await}) {}", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("var O = { async f({isAsync: await}) {}", "Can't use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var O = { async f(await) {} } ", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var O = { async f([await]) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var O = { async f([...await]) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var O = { async f(...await) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var O = { async f({await}) {}", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("var O = { async f({isAsync: await}) {}", "Cannot use 'await' as a parameter name in an async function.");
 
 // AsyncFunction constructor
-shouldThrowSyntaxError("AsyncFunction('var await;')", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('var [await] = [];')", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('var [...await] = [];')", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('var {await} = {};')", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('var {isAsync: await} = {};')", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('var {isAsync: await} = {};')", "Can't use 'await' as a variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('let await;')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('let [await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('let [...await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('let {await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('let {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('let {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('const await;')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('const [await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('const [...await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('const {await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('const {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('const {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('var await;')", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('var [await] = [];')", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('var [...await] = [];')", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('var {await} = {};')", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('var {isAsync: await} = {};')", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('var {isAsync: await} = {};')", "Cannot use 'await' as a variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('let await;')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('let [await] = [];')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('let [...await] = [];')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('let {await} = {};')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('let {isAsync: await} = {};')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('let {isAsync: await} = {};')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('const await;')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('const [await] = [];')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('const [...await] = [];')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('const {await} = {};')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('const {isAsync: await} = {};')", "Cannot use 'await' as a lexical variable name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('const {isAsync: await} = {};')", "Cannot use 'await' as a lexical variable name in an async function.");
 shouldThrowSyntaxError("AsyncFunction('function await() {}')", "Cannot declare function named 'await' in an async function.");
 shouldThrowSyntaxError("AsyncFunction('async function await() {}')", "Cannot declare function named 'await' in an async function.");
-shouldThrowSyntaxError("AsyncFunction('await', '')", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('[await]', '')", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('[...await]', '')", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('...await', '')", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('{await}', '')", "Can't use 'await' as a parameter name in an async function.");
-shouldThrowSyntaxError("AsyncFunction('{isAsync: await}', '')", "Can't use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('await', '')", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('[await]', '')", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('[...await]', '')", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('...await', '')", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('{await}', '')", "Cannot use 'await' as a parameter name in an async function.");
+shouldThrowSyntaxError("AsyncFunction('{isAsync: await}', '')", "Cannot use 'await' as a parameter name in an async function.");
index d76457a..68f855f 100644 (file)
@@ -60,7 +60,7 @@ testSyntaxError(`
     } catch (let) {
     }
 })
-`, `SyntaxError: Cannot use the keyword 'let' as a catch parameter name.`);
+`, `SyntaxError: Cannot use 'let' as a catch parameter name in strict mode.`);
 
 testSyntaxError(`
 (function () {
@@ -69,7 +69,7 @@ testSyntaxError(`
     } catch ([let]) {
     }
 })
-`, `SyntaxError: Cannot use the keyword 'let' as a catch parameter name.`);
+`, `SyntaxError: Cannot use 'let' as a catch parameter name in strict mode.`);
 
 
 testSyntax(`
@@ -95,7 +95,7 @@ testSyntaxError(`
     } catch (yield) {
     }
 })
-`, `SyntaxError: Cannot use the keyword 'yield' as a catch parameter name.`);
+`, `SyntaxError: Cannot use 'yield' as a catch parameter name in strict mode.`);
 
 testSyntaxError(`
 (function () {
@@ -104,7 +104,7 @@ testSyntaxError(`
     } catch ([yield]) {
     }
 })
-`, `SyntaxError: Cannot use the keyword 'yield' as a catch parameter name.`);
+`, `SyntaxError: Cannot use 'yield' as a catch parameter name in strict mode.`);
 
 testSyntaxError(`
 (function () {
@@ -152,7 +152,7 @@ testSyntaxError(`
     } catch (yield) {
     }
 })
-`, `SyntaxError: Cannot use the keyword 'yield' as a catch parameter name.`);
+`, `SyntaxError: Cannot use 'yield' as a catch parameter name in a generator function.`);
 
 testSyntax(`
 (function *() {
index 0082c21..99a99ba 100644 (file)
@@ -29,12 +29,22 @@ function *test() {
         }
     }
 }
+`, `SyntaxError: Cannot use 'yield' as a label in a generator function.`);
+
+testSyntaxError(`
+function *test() {
+    {
+        label: for (var i = 0; i < 1000; ++i) {
+            break yield;
+        }
+    }
+}
 `, `SyntaxError: Unexpected keyword 'yield'. Expected an identifier as the target for a break statement.`);
 
 testSyntaxError(`
 function *test() {
     {
-        yield: for (var i = 0; i < 1000; ++i) {
+        label: for (var i = 0; i < 1000; ++i) {
             continue yield;
         }
     }
index 5779b2f..009a3a6 100644 (file)
@@ -39,13 +39,24 @@ function test() {
         }
     }
 }
+`, `SyntaxError: Cannot use 'yield' as a label in strict mode.`);
+
+testSyntaxError(`
+function test() {
+    "use strict";
+    {
+        label: for (var i = 0; i < 1000; ++i) {
+            break yield;
+        }
+    }
+}
 `, `SyntaxError: Unexpected keyword 'yield'. Expected an identifier as the target for a break statement.`);
 
 testSyntaxError(`
 function test() {
     "use strict";
     {
-        yield: for (var i = 0; i < 1000; ++i) {
+        label: for (var i = 0; i < 1000; ++i) {
             continue yield;
         }
     }
index 86e6426..3fe8046 100644 (file)
@@ -25,17 +25,17 @@ testSyntaxError(`
 function *t1() {
     var yield = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a variable name in a generator function.`);
 testSyntaxError(`
 function *t1() {
     let yield = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in a generator function.`);
 testSyntaxError(`
 function *t1() {
     const yield = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in a generator function.`);
 
 testSyntaxError(`
 function *t1() {
@@ -57,39 +57,39 @@ testSyntaxError(`
 function *t1() {
     var { i: yield } = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a variable name in a generator function.`);
 testSyntaxError(`
 function *t1() {
     let { i: yield } = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in a generator function.`);
 testSyntaxError(`
 function *t1() {
     const { i: yield } = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in a generator function.`);
 
 testSyntaxError(`
 function *t1() {
     var [ yield ] = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a variable name in a generator function.`);
 testSyntaxError(`
 function *t1() {
     let [ yield ] = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in a generator function.`);
 testSyntaxError(`
 function *t1() {
     const [ yield ] = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in a generator function.`);
 
 testSyntaxError(`
 function *t1() {
     function yield() { }
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a function name.`);
+`, `SyntaxError: Unexpected keyword 'yield'`);
 testSyntax(`
 function t1() {
     function *yield() {
@@ -103,7 +103,7 @@ function *t1() {
     } catch (yield) {
     }
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a catch parameter name.`);
+`, `SyntaxError: Cannot use 'yield' as a catch parameter name in a generator function.`);
 
 testSyntax(`
 function *t1() {
index 38bf6f8..3809b32 100644 (file)
@@ -42,19 +42,19 @@ function t1() {
     "use strict";
     var yield = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a variable name in strict mode.`);
 testSyntaxError(`
 function t1() {
     "use strict";
     let yield = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in strict mode.`);
 testSyntaxError(`
 function t1() {
     "use strict";
     const yield = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in strict mode.`);
 
 testSyntax(`
 function t1() {
@@ -112,19 +112,19 @@ function t1() {
     "use strict";
     var { i: yield } = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a variable name in strict mode.`);
 testSyntaxError(`
 function t1() {
     "use strict";
     let { i: yield } = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in strict mode.`);
 testSyntaxError(`
 function t1() {
     "use strict";
     const { i: yield } = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in strict mode.`);
 
 testSyntax(`
 function t1() {
@@ -147,19 +147,19 @@ function t1() {
     "use strict";
     var [ yield ] = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a variable name in strict mode.`);
 testSyntaxError(`
 function t1() {
     "use strict";
     let [ yield ] = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in strict mode.`);
 testSyntaxError(`
 function t1() {
     "use strict";
     const [ yield ] = 20;
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a lexical variable name.`);
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in strict mode.`);
 
 testSyntax(`
 function t1() {
@@ -171,7 +171,7 @@ function t1() {
     "use strict";
     function yield() { }
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a function name.`);
+`, `SyntaxError: Cannot use 'yield' as a function name in strict mode.`);
 
 testSyntax(`
 function t1() {
@@ -187,7 +187,7 @@ function t1() {
     } catch (yield) {
     }
 }
-`, `SyntaxError: Cannot use the keyword 'yield' as a catch parameter name.`);
+`, `SyntaxError: Cannot use 'yield' as a catch parameter name in strict mode.`);
 
 testSyntax(`
 function t1() {
diff --git a/JSTests/stress/yield-reserved-word.js b/JSTests/stress/yield-reserved-word.js
new file mode 100644 (file)
index 0000000..e6c5ef2
--- /dev/null
@@ -0,0 +1,196 @@
+function shouldNotThrow(func) {
+    let error;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (error)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+function shouldThrow(func, errorMessage) {
+    let errorThrown = false;
+    let error;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+function checkClassicNoSyntaxError(source) {
+    shouldNotThrow(() => eval(source));
+}
+
+function checkClassicSyntaxError(source, errorMessage) {
+    shouldThrow(() => eval(source), errorMessage);
+}
+
+function checkStrictSyntaxError(source, errorMessage) {
+    shouldThrow(() => checkModuleSyntax(source), errorMessage);
+}
+
+
+function checkNoSyntaxErrorCases(source) {
+    checkClassicNoSyntaxError(source);
+
+    // A nested function within a generator is allowed to use the "yield" name again
+    // within its body because they have FunctionBody[~Yield]. Same with method bodies.
+    checkClassicNoSyntaxError(`function *gen() { function f() { ${source} } }`);
+    checkClassicNoSyntaxError(`function *gen() { async function f() { ${source} } }`);
+    checkClassicNoSyntaxError(`function *gen() { let f = () => { ${source} } }`);
+    checkClassicNoSyntaxError(`function *gen() { let f = async () => { ${source} } }`);
+    checkClassicNoSyntaxError(`function *gen() { var o = { f() { ${source} } } }`);
+    checkClassicNoSyntaxError(`function *gen() { var o = { async f() { ${source} } } }`);
+    checkClassicNoSyntaxError(`function *gen() { var o = { get f() { ${source} } } }`);
+    checkClassicNoSyntaxError(`function *gen() { var o = { set f(x) { ${source} } } }`);
+}
+
+
+checkNoSyntaxErrorCases(`var yield`);
+checkNoSyntaxErrorCases(`let yield`);
+checkNoSyntaxErrorCases(`const yield = 1`);
+checkNoSyntaxErrorCases(`var {yield} = {}`);
+checkNoSyntaxErrorCases(`yield: 1`);
+checkNoSyntaxErrorCases(`function yield(){}`);
+checkNoSyntaxErrorCases(`function foo(yield){}`);
+
+checkNoSyntaxErrorCases(`(class { *yield(){} })`); // GeneratorMethod allows "yield" due to PropertyName[?Yield].
+checkNoSyntaxErrorCases(`function *yield(){}`); // GeneratorDeclaration allows "yield" name due to BindingIdentifier[?Yield].
+
+checkNoSyntaxErrorCases(`var o = { yield(yield){ var yield } }`); // PropertyName[?Yield] ( UniqueFormalParameters[~Yield] ) { FunctionBody[~Yield] }
+checkNoSyntaxErrorCases(`var o = { *yield(){} }`); // GeneratorMethod[?Yield]
+checkNoSyntaxErrorCases(`var o = { async yield(){} }`); // AsyncMethod[?Yield]
+checkNoSyntaxErrorCases(`var o = { get x(){ var yield } }`); // get PropertyName[?Yield] () { FunctionBody[~Yield] }
+checkNoSyntaxErrorCases(`var o = { set x(yield){} }`); // set PropertyName[?Yield] ( PropertySetParameterList) { FunctionBody[~Yield] }
+checkNoSyntaxErrorCases(`var o = { set x(yield){} }`); // PropertySetParameterList : FormalParameter[~Yield]
+
+
+// Disallowed inside a generator.
+
+checkClassicSyntaxError(`
+function* foo() { yield: 1; }
+`, `SyntaxError: Cannot use 'yield' as a label in a generator function.`);
+
+checkClassicSyntaxError(`
+function* foo() { var yield; }
+`, `SyntaxError: Cannot use 'yield' as a variable name in a generator function.`);
+
+checkClassicSyntaxError(`
+function* foo() { let yield; }
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in a generator function.`);
+
+checkClassicSyntaxError(`
+function* foo() { var {yield} = {}; }
+`, `SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'yield'.`);
+
+checkClassicSyntaxError(`
+function* foo(yield){}
+`, `SyntaxError: Cannot use 'yield' as a parameter name in a generator function.`);
+
+// GeneratorExpression BindingIdentifier[+Yield] on the name.
+checkClassicSyntaxError(`
+(function* yield() { })
+`, `SyntaxError: Cannot declare generator function named 'yield'.`);
+
+// GeneratorDeclaration BindingIdentifier[?Yield] on the name.
+checkClassicSyntaxError(`
+function* foo() { function* yield(){} }
+`, `SyntaxError: Cannot use 'yield' as a generator function name in a generator function.`);
+
+// class BindingIdentifier[?Yield] on the name.
+checkClassicSyntaxError(`
+function* gen() { (class yield {}) }
+`, `SyntaxError: Unexpected keyword 'yield'. Expected opening '{' at the start of a class body.`);
+
+
+// Disallowed in strict code.
+
+checkStrictSyntaxError(`
+function* foo() { yield: 1; }
+`, `SyntaxError: Cannot use 'yield' as a label in strict mode.:2`);
+
+checkStrictSyntaxError(`
+var yield;
+`, `SyntaxError: Cannot use 'yield' as a variable name in strict mode.:2`);
+
+checkStrictSyntaxError(`
+let yield;
+`, `SyntaxError: Cannot use 'yield' as a lexical variable name in strict mode.:2`);
+
+checkStrictSyntaxError(`
+var {yield} = {};
+`, `SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'yield'.:2`);
+
+checkStrictSyntaxError(`
+yield: 1
+`, `SyntaxError: Cannot use 'yield' as a label in strict mode.:2`);
+
+checkStrictSyntaxError(`
+import {yield} from 'foo'
+`, `SyntaxError: Cannot use keyword as imported binding name.:2`);
+
+checkStrictSyntaxError(`
+function* foo(yield){}
+`, `SyntaxError: Cannot use 'yield' as a parameter name in strict mode.:2`);
+
+checkStrictSyntaxError(`
+function* yield(){}
+`, `SyntaxError: Cannot use 'yield' as a generator function name in strict mode.:2`);
+
+checkStrictSyntaxError(`
+(function* yield(){})
+`, `SyntaxError: Cannot use 'yield' as a generator function name in strict mode.:2`);
+
+checkStrictSyntaxError(`
+function* gen() { (class yield {}) }
+`, `SyntaxError: Unexpected keyword 'yield'. Expected opening '{' at the start of a class body.:2`);
+
+checkClassicSyntaxError(`
+function *get() { var o = { yield }; }
+`, `SyntaxError: Cannot use 'yield' as a shorthand property name in a generator function.`);
+
+
+// Edge cases where ~Yield re-enables use of yield in non-strict code.
+
+// FunctionDeclaration[Yield]:
+//   function BindingIdentifier[?Yield] ( FormalParameters[~Yield] ) { FunctionBody[~Yield] }
+checkClassicSyntaxError(`function *gen() { function yield() {} }`, `SyntaxError: Unexpected keyword 'yield'`);
+checkClassicNoSyntaxError(`function *gen() { function f(yield) {} }`);
+
+// FunctionExpression:
+//   function BindingIdentifier[~Yield]opt ( FormalParameters[~Yield] ) { FunctionBody[~Yield] }
+checkClassicNoSyntaxError(`function *gen() { (function yield() {}) }`);
+checkClassicNoSyntaxError(`function *gen() { (function f(yield) {}) }`)
+checkClassicNoSyntaxError(`function *gen() { (function yield(yield) {}) }`)
+checkClassicNoSyntaxError(`function *gen() { (function(yield) {}) }`);
+
+// AsyncFunctionDeclaration[Yield]:
+//     async function BindingIdentifier[?Yield] ( FormalParameters[~Yield]) { AsyncFunctionBody }
+checkClassicSyntaxError(`function *gen() { async function yield() {} }`, `SyntaxError: Unexpected keyword 'yield'`);
+checkClassicNoSyntaxError(`function *gen() { async function f(yield) {} }`);
+
+// AsyncFunctionExpression:
+//     async function BindingIdentifier[~Yield]opt ( FormalParameters[~Yield] ) { AsyncFunctionBody }
+checkClassicNoSyntaxError(`function *gen() { (async function yield() {}) }`);
+checkClassicNoSyntaxError(`function *gen() { (async function f(yield) {}) }`)
+checkClassicNoSyntaxError(`function *gen() { (async function yield(yield) {}) }`);
+checkClassicNoSyntaxError(`function *gen() { (async function(yield) {}) }`);
+
+// ArrowFunction[Yield]:
+//     ArrowParameters[?Yield] => ConciseBody
+checkClassicSyntaxError(`function *gen() { let f = (yield) => {} }`, `SyntaxError: Cannot use 'yield' as a parameter name in a generator function.`);
+
+// ArrowFunction[Yield]:
+//     ArrowParameters[?Yield] => ConciseBody
+checkClassicSyntaxError(`function *gen() { let f = (yield) => {} }`, `SyntaxError: Cannot use 'yield' as a parameter name in a generator function.`);
+
+// AsyncArrowFunction[Yield]:
+//     async AsyncArrowBindingIdentifier[?Yield] => AsyncConciseBody
+checkClassicSyntaxError(`function *gen() { let f = async (yield) => {} }`, `SyntaxError: Cannot use 'yield' as a parameter name in a generator function.`);
index 6f496f7..574ef7d 100644 (file)
 - path: test262/test/language/expressions/generators/yield-as-function-expression-binding-identifier.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/generators/yield-as-generator-expression-binding-identifier.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/generators/yield-as-identifier-in-nested-function.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/generators/yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/generators/yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/expressions/generators/yield-as-literal-property-name.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/generators/yield-as-literal-property-name.js
 - path: test262/test/language/expressions/object/method-definition/yield-as-identifier-in-nested-function.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/object/method-definition/yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/object/method-definition/yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/expressions/object/method-definition/yield-as-literal-property-name.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/object/method-definition/yield-as-literal-property-name.js
 - path: test262/test/language/statements/class/definition/methods-gen-yield-as-identifier-in-nested-function.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/definition/methods-gen-yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/definition/methods-gen-yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/definition/methods-gen-yield-as-literal-property-name.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/definition/methods-gen-yield-as-literal-property-name.js
 - path: test262/test/language/statements/for-in/dstr-array-rest-yield-ident-invalid.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-in/dstr-obj-id-identifier-yield-expr.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-in/dstr-obj-id-identifier-yield-ident-invalid.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-in/dstr-obj-id-init-simple-strict.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-in/dstr-obj-id-init-yield-ident-invalid.js
 - path: test262/test/language/statements/for-of/dstr-obj-id-identifier-resolution-trlng.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-of/dstr-obj-id-identifier-yield-expr.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-of/dstr-obj-id-identifier-yield-ident-invalid.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-of/dstr-obj-id-identifier-yield-ident-valid.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-of/dstr-obj-id-init-assignment-missing.js
 - path: test262/test/language/statements/generators/yield-as-identifier-in-nested-function.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/generators/yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/generators/yield-as-label.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/generators/yield-as-literal-property-name.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/generators/yield-as-literal-property-name.js
 - path: test262/test/language/statements/labeled/value-yield-non-strict.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/labeled/value-yield-strict.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/let/block-local-closure-get-before-initialization.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/let/block-local-closure-get-before-initialization.js
index 5289706..6a10f22 100644 (file)
@@ -1,3 +1,19 @@
+2017-04-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        test262: test262/test/language/expressions/generators/yield-as-label.js
+        https://bugs.webkit.org/show_bug.cgi?id=170979
+
+        Reviewed by Saam Barati.
+
+        * js/object-literal-shorthand-construction-expected.txt:
+        * js/script-tests/object-literal-shorthand-construction.js:
+        Extend this test to cover object literal shorthand with keywords.
+
+        * js/dom/reserved-words-as-property-expected.txt:
+        * js/let-syntax-expected.txt:
+        * js/parser-syntax-check-expected.txt:
+        Improved error messages.
+
 2017-04-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r215674.
index adb07c9..2b61f20 100644 (file)
@@ -1353,18 +1353,18 @@ PASS ({ let: 42 }.let === 42) is true
 PASS (function(){({ let: 42 }.let === 42)}); true is true
 PASS ({ get let(){}, set let(x){}, parsedOkay: 42 }.parsedOkay === 42) is true
 PASS (function(){({ get let(){}, set let(x){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var let; true threw exception SyntaxError: Cannot use the keyword 'let' as a variable name..
-PASS (function(){"use strict";var let; true}); true threw exception SyntaxError: Cannot use the keyword 'let' as a variable name..
-PASS "use strict";var let = 42; let === 42 threw exception SyntaxError: Cannot use the keyword 'let' as a variable name..
-PASS (function(){"use strict";var let = 42; let === 42}); true threw exception SyntaxError: Cannot use the keyword 'let' as a variable name..
-PASS "use strict";function g(let){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'let' as a parameter name..
-PASS (function(){"use strict";function g(let){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'let' as a parameter name..
-PASS "use strict";/let/.test(function g(let){ "use strict"; }) threw exception SyntaxError: Cannot use the keyword 'let' as a parameter name..
-PASS (function(){"use strict";/let/.test(function g(let){ "use strict"; })}); true threw exception SyntaxError: Cannot use the keyword 'let' as a parameter name..
-PASS "use strict";try{}catch(let){}; true threw exception SyntaxError: Cannot use the keyword 'let' as a catch parameter name..
-PASS (function(){"use strict";try{}catch(let){}; true}); true threw exception SyntaxError: Cannot use the keyword 'let' as a catch parameter name..
-PASS "use strict";function let(){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'let' as a function name..
-PASS (function(){"use strict";function let(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'let' as a function name..
+PASS "use strict";var let; true threw exception SyntaxError: Cannot use 'let' as a variable name in strict mode..
+PASS (function(){"use strict";var let; true}); true threw exception SyntaxError: Cannot use 'let' as a variable name in strict mode..
+PASS "use strict";var let = 42; let === 42 threw exception SyntaxError: Cannot use 'let' as a variable name in strict mode..
+PASS (function(){"use strict";var let = 42; let === 42}); true threw exception SyntaxError: Cannot use 'let' as a variable name in strict mode..
+PASS "use strict";function g(let){ "use strict"; }; true threw exception SyntaxError: Cannot use 'let' as a parameter name in strict mode..
+PASS (function(){"use strict";function g(let){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use 'let' as a parameter name in strict mode..
+PASS "use strict";/let/.test(function g(let){ "use strict"; }) threw exception SyntaxError: Cannot use 'let' as a parameter name in strict mode..
+PASS (function(){"use strict";/let/.test(function g(let){ "use strict"; })}); true threw exception SyntaxError: Cannot use 'let' as a parameter name in strict mode..
+PASS "use strict";try{}catch(let){}; true threw exception SyntaxError: Cannot use 'let' as a catch parameter name in strict mode..
+PASS (function(){"use strict";try{}catch(let){}; true}); true threw exception SyntaxError: Cannot use 'let' as a catch parameter name in strict mode..
+PASS "use strict";function let(){ "use strict"; }; true threw exception SyntaxError: Cannot use 'let' as a function name in strict mode..
+PASS (function(){"use strict";function let(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use 'let' as a function name in strict mode..
 PASS "use strict";({ "let": 42 }.let === 42) is true
 PASS (function(){"use strict";({ "let": 42 }.let === 42)}); true is true
 PASS "use strict";({ let: 42 }.let === 42) is true
@@ -1461,18 +1461,18 @@ PASS ({ yield: 42 }.yield === 42) is true
 PASS (function(){({ yield: 42 }.yield === 42)}); true is true
 PASS ({ get yield(){}, set yield(x){}, parsedOkay: 42 }.parsedOkay === 42) is true
 PASS (function(){({ get yield(){}, set yield(x){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var yield; true threw exception SyntaxError: Cannot use the keyword 'yield' as a variable name..
-PASS (function(){"use strict";var yield; true}); true threw exception SyntaxError: Cannot use the keyword 'yield' as a variable name..
-PASS "use strict";var yield = 42; yield === 42 threw exception SyntaxError: Cannot use the keyword 'yield' as a variable name..
-PASS (function(){"use strict";var yield = 42; yield === 42}); true threw exception SyntaxError: Cannot use the keyword 'yield' as a variable name..
-PASS "use strict";function g(yield){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'yield' as a parameter name..
-PASS (function(){"use strict";function g(yield){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'yield' as a parameter name..
-PASS "use strict";/yield/.test(function g(yield){ "use strict"; }) threw exception SyntaxError: Cannot use the keyword 'yield' as a parameter name..
-PASS (function(){"use strict";/yield/.test(function g(yield){ "use strict"; })}); true threw exception SyntaxError: Cannot use the keyword 'yield' as a parameter name..
-PASS "use strict";try{}catch(yield){}; true threw exception SyntaxError: Cannot use the keyword 'yield' as a catch parameter name..
-PASS (function(){"use strict";try{}catch(yield){}; true}); true threw exception SyntaxError: Cannot use the keyword 'yield' as a catch parameter name..
-PASS "use strict";function yield(){ "use strict"; }; true threw exception SyntaxError: Cannot use the keyword 'yield' as a function name..
-PASS (function(){"use strict";function yield(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use the keyword 'yield' as a function name..
+PASS "use strict";var yield; true threw exception SyntaxError: Cannot use 'yield' as a variable name in strict mode..
+PASS (function(){"use strict";var yield; true}); true threw exception SyntaxError: Cannot use 'yield' as a variable name in strict mode..
+PASS "use strict";var yield = 42; yield === 42 threw exception SyntaxError: Cannot use 'yield' as a variable name in strict mode..
+PASS (function(){"use strict";var yield = 42; yield === 42}); true threw exception SyntaxError: Cannot use 'yield' as a variable name in strict mode..
+PASS "use strict";function g(yield){ "use strict"; }; true threw exception SyntaxError: Cannot use 'yield' as a parameter name in strict mode..
+PASS (function(){"use strict";function g(yield){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use 'yield' as a parameter name in strict mode..
+PASS "use strict";/yield/.test(function g(yield){ "use strict"; }) threw exception SyntaxError: Cannot use 'yield' as a parameter name in strict mode..
+PASS (function(){"use strict";/yield/.test(function g(yield){ "use strict"; })}); true threw exception SyntaxError: Cannot use 'yield' as a parameter name in strict mode..
+PASS "use strict";try{}catch(yield){}; true threw exception SyntaxError: Cannot use 'yield' as a catch parameter name in strict mode..
+PASS (function(){"use strict";try{}catch(yield){}; true}); true threw exception SyntaxError: Cannot use 'yield' as a catch parameter name in strict mode..
+PASS "use strict";function yield(){ "use strict"; }; true threw exception SyntaxError: Cannot use 'yield' as a function name in strict mode..
+PASS (function(){"use strict";function yield(){ "use strict"; }; true}); true threw exception SyntaxError: Cannot use 'yield' as a function name in strict mode..
 PASS "use strict";({ "yield": 42 }.yield === 42) is true
 PASS (function(){"use strict";({ "yield": 42 }.yield === 42)}); true is true
 PASS "use strict";({ yield: 42 }.yield === 42) is true
index a891cf0..9dc5677 100644 (file)
@@ -70,41 +70,41 @@ PASS Does not have syntax error: ''use strict'; let x = { get foo() { let foo =
 PASS Does not have syntax error: 'let x = { get foo() { class foo { } } };'
 PASS Does not have syntax error: ''use strict'; let x = { get foo() { class foo { } } };'
 PASS Does not have syntax error: 'let x; with ({}) let: y = 3;'
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
 PASS Has syntax error: 'let let;'
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
 PASS Has syntax error: ''use strict'; let let;'
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
 PASS Has syntax error: 'const let;'
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
 PASS Has syntax error: ''use strict'; const let;'
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
 PASS Has syntax error: 'let {let};'
 SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'let'.
 SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'let'.
 PASS Has syntax error: ''use strict'; let {let};'
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
 PASS Has syntax error: 'let {l: let};'
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
 PASS Has syntax error: ''use strict'; let {l: let};'
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
 PASS Has syntax error: 'let {l: {let}};'
 SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'let'.
 SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'let'.
 PASS Has syntax error: ''use strict'; let {l: {let}};'
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
 PASS Has syntax error: 'let {l: [let]};'
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
 PASS Has syntax error: ''use strict'; let {l: [let]};'
 SyntaxError: Unexpected token ';'. Expected an initializer in destructuring variable declaration.
 SyntaxError: Unexpected token ';'. Expected an initializer in destructuring variable declaration.
@@ -238,11 +238,11 @@ PASS Has syntax error: 'function foo() {}; function bar(){} let baz, {f: [bar]}
 SyntaxError: Unexpected identifier 'bar'. Cannot declare a lexical variable twice: 'bar'.
 SyntaxError: Unexpected identifier 'bar'. Cannot declare a lexical variable twice: 'bar'.
 PASS Has syntax error: ''use strict'; function foo() {}; function bar(){} let baz, {f: [bar]} = {f:[10]};'
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
-SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
+SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration.
 PASS Has syntax error: 'for (let let = 0; let < 10; let++) {}'
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
-SyntaxError: Cannot use the keyword 'let' as a lexical variable name.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
+SyntaxError: Cannot use 'let' as a lexical variable name in strict mode.
 PASS Has syntax error: ''use strict'; for (let let = 0; let < 10; let++) {}'
 SyntaxError: Unexpected token '['. Expected either 'in' or 'of' in enumeration syntax.
 SyntaxError: Unexpected token '['. Expected either 'in' or 'of' in enumeration syntax.
@@ -397,8 +397,8 @@ SyntaxError: Unexpected token ';'. Expected a parameter pattern or a ')' in para
 SyntaxError: Unexpected token ';'. Expected a parameter pattern or a ')' in parameter list.
 PASS Has syntax error: ''use strict'; let;'
 PASS Does not have syntax error: 'var let;'
-SyntaxError: Cannot use the keyword 'let' as a variable name.
-SyntaxError: Cannot use the keyword 'let' as a variable name.
+SyntaxError: Cannot use 'let' as a variable name in strict mode.
+SyntaxError: Cannot use 'let' as a variable name in strict mode.
 PASS Has syntax error: ''use strict'; var let;'
 PASS Does not have syntax error: 'var {let} = 40;'
 SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'let'.
@@ -406,16 +406,16 @@ SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'let'.
 PASS Has syntax error: ''use strict'; var {let} = 40;'
 TypeError: [let] is not a function. (In '[let]', '[let]' is undefined)
 PASS Does not have syntax error: 'var [let] = 40;'
-SyntaxError: Cannot use the keyword 'let' as a variable name.
-SyntaxError: Cannot use the keyword 'let' as a variable name.
+SyntaxError: Cannot use 'let' as a variable name in strict mode.
+SyntaxError: Cannot use 'let' as a variable name in strict mode.
 PASS Has syntax error: ''use strict'; var [let] = 40;'
 PASS Does not have syntax error: 'var {p: let} = 40;'
-SyntaxError: Cannot use the keyword 'let' as a variable name.
-SyntaxError: Cannot use the keyword 'let' as a variable name.
+SyntaxError: Cannot use 'let' as a variable name in strict mode.
+SyntaxError: Cannot use 'let' as a variable name in strict mode.
 PASS Has syntax error: ''use strict'; var {p: let} = 40;'
 PASS Does not have syntax error: '(function test(let){});'
-SyntaxError: Cannot use the keyword 'let' as a parameter name.
-SyntaxError: Cannot use the keyword 'let' as a parameter name.
+SyntaxError: Cannot use 'let' as a parameter name in strict mode.
+SyntaxError: Cannot use 'let' as a parameter name in strict mode.
 PASS Has syntax error: ''use strict'; (function test(let){});'
 PASS Does not have syntax error: 'let: for (v of []) break let;'
 SyntaxError: Unexpected token ':'. Expected a parameter pattern or a ')' in parameter list.
@@ -438,8 +438,8 @@ SyntaxError: Unexpected token ':'. Expected a parameter pattern or a ')' in para
 SyntaxError: Unexpected token ':'. Expected a parameter pattern or a ')' in parameter list.
 PASS Has syntax error: ''use strict'; let: for (var v = 0; false; ) {};'
 PASS Does not have syntax error: 'try { } catch(let) {}'
-SyntaxError: Cannot use the keyword 'let' as a catch parameter name.
-SyntaxError: Cannot use the keyword 'let' as a catch parameter name.
+SyntaxError: Cannot use 'let' as a catch parameter name in strict mode.
+SyntaxError: Cannot use 'let' as a catch parameter name in strict mode.
 PASS Has syntax error: ''use strict'; try { } catch(let) {}'
 PASS Does not have syntax error: 'let x; if (true) let: x = 3;'
 SyntaxError: Unexpected keyword 'let'
index e2c41ee..ee16b85 100644 (file)
@@ -65,6 +65,50 @@ PASS this.__proto__ = [] threw exception TypeError: Cannot set prototype of immu
 PASS ({__proto__: this.__proto__}) instanceof Array is false
 PASS __proto__ = [] threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
 PASS ({__proto__: __proto__}) instanceof Array threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
+SyntaxErrors
+PASS ({break}) threw exception SyntaxError: Cannot use the keyword 'break' as a shorthand property name..
+PASS ({case}) threw exception SyntaxError: Cannot use the keyword 'case' as a shorthand property name..
+PASS ({catch}) threw exception SyntaxError: Cannot use the keyword 'catch' as a shorthand property name..
+PASS ({class}) threw exception SyntaxError: Cannot use the keyword 'class' as a shorthand property name..
+PASS ({const}) threw exception SyntaxError: Cannot use the keyword 'const' as a shorthand property name..
+PASS ({continue}) threw exception SyntaxError: Cannot use the keyword 'continue' as a shorthand property name..
+PASS ({debugger}) threw exception SyntaxError: Cannot use the keyword 'debugger' as a shorthand property name..
+PASS ({default}) threw exception SyntaxError: Cannot use the keyword 'default' as a shorthand property name..
+PASS ({delete}) threw exception SyntaxError: Cannot use the keyword 'delete' as a shorthand property name..
+PASS ({do}) threw exception SyntaxError: Cannot use the keyword 'do' as a shorthand property name..
+PASS ({else}) threw exception SyntaxError: Cannot use the keyword 'else' as a shorthand property name..
+PASS ({enum}) threw exception SyntaxError: Cannot use the reserved word 'enum' as a shorthand property name..
+PASS ({export}) threw exception SyntaxError: Cannot use the keyword 'export' as a shorthand property name..
+PASS ({extends}) threw exception SyntaxError: Cannot use the keyword 'extends' as a shorthand property name..
+PASS ({false}) threw exception SyntaxError: Cannot use the keyword 'false' as a shorthand property name..
+PASS ({finally}) threw exception SyntaxError: Cannot use the keyword 'finally' as a shorthand property name..
+PASS ({for}) threw exception SyntaxError: Cannot use the keyword 'for' as a shorthand property name..
+PASS ({function}) threw exception SyntaxError: Cannot use the keyword 'function' as a shorthand property name..
+PASS ({if}) threw exception SyntaxError: Cannot use the keyword 'if' as a shorthand property name..
+PASS ({import}) threw exception SyntaxError: Cannot use the keyword 'import' as a shorthand property name..
+PASS ({in}) threw exception SyntaxError: Cannot use the keyword 'in' as a shorthand property name..
+PASS ({instanceof}) threw exception SyntaxError: Cannot use the keyword 'instanceof' as a shorthand property name..
+PASS ({new}) threw exception SyntaxError: Cannot use the keyword 'new' as a shorthand property name..
+PASS ({null}) threw exception SyntaxError: Cannot use the keyword 'null' as a shorthand property name..
+PASS ({return}) threw exception SyntaxError: Cannot use the keyword 'return' as a shorthand property name..
+PASS ({super}) threw exception SyntaxError: Cannot use the keyword 'super' as a shorthand property name..
+PASS ({switch}) threw exception SyntaxError: Cannot use the keyword 'switch' as a shorthand property name..
+PASS ({throw}) threw exception SyntaxError: Cannot use the keyword 'throw' as a shorthand property name..
+PASS ({true}) threw exception SyntaxError: Cannot use the keyword 'true' as a shorthand property name..
+PASS ({try}) threw exception SyntaxError: Cannot use the keyword 'try' as a shorthand property name..
+PASS ({typeof}) threw exception SyntaxError: Cannot use the keyword 'typeof' as a shorthand property name..
+PASS ({var}) threw exception SyntaxError: Cannot use the keyword 'var' as a shorthand property name..
+PASS ({void}) threw exception SyntaxError: Cannot use the keyword 'void' as a shorthand property name..
+PASS ({while}) threw exception SyntaxError: Cannot use the keyword 'while' as a shorthand property name..
+PASS ({with}) threw exception SyntaxError: Cannot use the keyword 'with' as a shorthand property name..
+Contextual Keywords
+PASS ({let}) threw exception ReferenceError: Can't find variable: let.
+PASS ({async}) threw exception ReferenceError: Can't find variable: async.
+PASS ({yield}) threw exception ReferenceError: Can't find variable: yield.
+PASS ({await}) threw exception ReferenceError: Can't find variable: await.
+PASS "use strict"; ({let}) } threw exception SyntaxError: Cannot use 'let' as a shorthand property name in strict mode..
+PASS function* generator() { ({yield}) } threw exception SyntaxError: Cannot use 'yield' as a shorthand property name in a generator function..
+PASS async function func() { ({await}) } threw exception SyntaxError: Cannot use 'await' as a shorthand property name in an async function..
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 691cc75..4f17c92 100644 (file)
@@ -452,18 +452,18 @@ PASS Valid:   "for (const x of []) { const x = 20; break; }"
 PASS Valid:   "function f() { for (const x of []) { const x = 20; break; } }"
 PASS Valid:   "for (const x in {}) { const x = 20; break; }"
 PASS Valid:   "function f() { for (const x in {}) { const x = 20; break; } }"
-PASS Invalid: "for (const let = 10; ; ) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "function f() { for (const let = 10; ; ) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "for (const let in {}) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "function f() { for (const let in {}) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "for (const let of []) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "function f() { for (const let of []) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "for (let let = 10; ; ) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "function f() { for (let let = 10; ; ) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "for (let let in {}) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "function f() { for (let let in {}) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "for (let let of []) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
-PASS Invalid: "function f() { for (let let of []) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Can't use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "for (const let = 10; ; ) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "function f() { for (const let = 10; ; ) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "for (const let in {}) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "function f() { for (const let in {}) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "for (const let of []) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "function f() { for (const let of []) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "for (let let = 10; ; ) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "function f() { for (let let = 10; ; ) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "for (let let in {}) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "function f() { for (let let in {}) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "for (let let of []) { break; }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
+PASS Invalid: "function f() { for (let let of []) { break; } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'. Cannot use 'let' as an identifier name for a LexicalDeclaration."
 PASS Invalid: "for ( %a ; ; ) { }". Produced the following syntax error: "SyntaxError: Unexpected token '%'"
 PASS Invalid: "function f() { for ( %a ; ; ) { } }". Produced the following syntax error: "SyntaxError: Unexpected token '%'"
 PASS Valid:   "for (a in b) break" with ReferenceError
@@ -800,8 +800,8 @@ PASS Valid:   "yield: function foo() { }"
 PASS Valid:   "function f() { yield: function foo() { } }"
 PASS Valid:   "yield: let: function foo() { }"
 PASS Valid:   "function f() { yield: let: function foo() { } }"
-PASS Invalid: "'use strict'; yield: let: function foo() { }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'"
-PASS Invalid: "function f() { 'use strict'; yield: let: function foo() { } }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'let'"
+PASS Invalid: "'use strict'; yield: let: function foo() { }". Produced the following syntax error: "SyntaxError: Cannot use 'yield' as a label in strict mode."
+PASS Invalid: "function f() { 'use strict'; yield: let: function foo() { } }". Produced the following syntax error: "SyntaxError: Cannot use 'yield' as a label in strict mode."
 PASS Valid:   "var str = "'use strict'; function f1(a) { function f2(b) { return b; } return f2(a); } return f1(arguments[0]);"; var foo = new Function(str); foo(5);"
 PASS Valid:   "function f() { var str = "'use strict'; function f1(a) { function f2(b) { return b; } return f2(a); } return f1(arguments[0]);"; var foo = new Function(str); foo(5); }"
 PASS Valid:   "var str = "'use strict'; function f1(a) { function f2(b) { function f3(c) { return c; } return f3(b); } return f2(a); } return f1(arguments[0]);"; var foo = new Function(str); foo(5);"
@@ -1250,14 +1250,14 @@ PASS Valid:   "function foo(...abc123) { }"
 PASS Valid:   "function f() { function foo(...abc123) { } }"
 PASS Valid:   "function foo(...let) { }"
 PASS Valid:   "function f() { function foo(...let) { } }"
-PASS Invalid: "'use strict'; function foo(...let) { }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'let' as a parameter name."
-PASS Invalid: "function f() { 'use strict'; function foo(...let) { } }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'let' as a parameter name."
-PASS Invalid: "'use strict'; function foo(...[let]) { }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'let' as a parameter name."
-PASS Invalid: "function f() { 'use strict'; function foo(...[let]) { } }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'let' as a parameter name."
+PASS Invalid: "'use strict'; function foo(...let) { }". Produced the following syntax error: "SyntaxError: Cannot use 'let' as a parameter name in strict mode."
+PASS Invalid: "function f() { 'use strict'; function foo(...let) { } }". Produced the following syntax error: "SyntaxError: Cannot use 'let' as a parameter name in strict mode."
+PASS Invalid: "'use strict'; function foo(...[let]) { }". Produced the following syntax error: "SyntaxError: Cannot use 'let' as a parameter name in strict mode."
+PASS Invalid: "function f() { 'use strict'; function foo(...[let]) { } }". Produced the following syntax error: "SyntaxError: Cannot use 'let' as a parameter name in strict mode."
 PASS Valid:   "function foo(...yield) { }"
 PASS Valid:   "function f() { function foo(...yield) { } }"
-PASS Invalid: "'use strict'; function foo(...yield) { }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'yield' as a parameter name."
-PASS Invalid: "function f() { 'use strict'; function foo(...yield) { } }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'yield' as a parameter name."
+PASS Invalid: "'use strict'; function foo(...yield) { }". Produced the following syntax error: "SyntaxError: Cannot use 'yield' as a parameter name in strict mode."
+PASS Invalid: "function f() { 'use strict'; function foo(...yield) { } }". Produced the following syntax error: "SyntaxError: Cannot use 'yield' as a parameter name in strict mode."
 PASS Invalid: "function foo(...if) { }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'if' as a parameter name."
 PASS Invalid: "function f() { function foo(...if) { } }". Produced the following syntax error: "SyntaxError: Cannot use the keyword 'if' as a parameter name."
 PASS Valid:   "let x = (...a) => { }"
index e13d767..0460b66 100644 (file)
@@ -114,3 +114,51 @@ shouldThrow("this.__proto__ = []");
 shouldBeFalse("({__proto__: this.__proto__}) instanceof Array");
 shouldThrow("__proto__ = []", '"TypeError: Object.prototype.__proto__ called on null or undefined"');
 shouldThrow("({__proto__: __proto__}) instanceof Array", '"TypeError: Object.prototype.__proto__ called on null or undefined"');
+
+// Keywords - Syntax Errors
+debug("SyntaxErrors");
+shouldThrow(`({break})`);
+shouldThrow(`({case})`);
+shouldThrow(`({catch})`);
+shouldThrow(`({class})`);
+shouldThrow(`({const})`);
+shouldThrow(`({continue})`);
+shouldThrow(`({debugger})`);
+shouldThrow(`({default})`);
+shouldThrow(`({delete})`);
+shouldThrow(`({do})`);
+shouldThrow(`({else})`);
+shouldThrow(`({enum})`);
+shouldThrow(`({export})`);
+shouldThrow(`({extends})`);
+shouldThrow(`({false})`);
+shouldThrow(`({finally})`);
+shouldThrow(`({for})`);
+shouldThrow(`({function})`);
+shouldThrow(`({if})`);
+shouldThrow(`({import})`);
+shouldThrow(`({in})`);
+shouldThrow(`({instanceof})`);
+shouldThrow(`({new})`);
+shouldThrow(`({null})`);
+shouldThrow(`({return})`);
+shouldThrow(`({super})`);
+shouldThrow(`({switch})`);
+shouldThrow(`({throw})`);
+shouldThrow(`({true})`);
+shouldThrow(`({try})`);
+shouldThrow(`({typeof})`);
+shouldThrow(`({var})`);
+shouldThrow(`({void})`);
+shouldThrow(`({while})`);
+shouldThrow(`({with})`);
+
+// Sometimes Keywords - yield and await become keywords in some cases
+debug("Contextual Keywords")
+shouldThrow(`({let})`); // ReferenceError
+shouldThrow(`({async})`); // ReferenceError
+shouldThrow(`({yield})`); // ReferenceError
+shouldThrow(`({await})`); // ReferenceError
+shouldThrow(`"use strict"; ({let}) }`); // SyntaxError
+shouldThrow(`function* generator() { ({yield}) }`); // SyntaxError
+shouldThrow(`async function func() { ({await}) }`); // SyntaxError
index bb04a32..98c1503 100644 (file)
@@ -1,3 +1,42 @@
+2017-04-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        test262: test262/test/language/expressions/generators/yield-as-label.js
+        https://bugs.webkit.org/show_bug.cgi?id=170979
+
+        Reviewed by Saam Barati.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVariableDeclarationList):
+        (JSC::Parser<LexerType>::parseDestructuringPattern):
+        (JSC::Parser<LexerType>::parseFormalParameters):
+        Converge on "Cannot" instead of "Can't" in error messages.
+
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        Disallow "yield" as the generator function name in function expressions.
+        This refers to the difference between Declaration and Expression, where
+        only GeneratorExpression explicitly has [+Yield] disallowing yield for
+        the generator name:
+
+            GeneratorDeclaration[Yield, Await, Default]:
+                function * BindingIdentifier[?Yield, ?Await] ...
+
+            GeneratorExpression:
+                function * BindingIdentifier[+Yield, ~Await]opt ...
+
+        (JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
+        Disallow "yield" as a label name in strict mode or inside a generator.
+
+        (JSC::Parser<LexerType>::parseProperty):
+        Disallow "yield" or any keyword in object literal shorthands.
+
+        * parser/Parser.h:
+        (JSC::Parser::getToken):
+        (JSC::Parser::isDisallowedIdentifierLet):
+        (JSC::Parser::isDisallowedIdentifierYield):
+        (JSC::Parser::disallowedIdentifierLetReason):
+        (JSC::Parser::disallowedIdentifierYieldReason):
+        Follow pattern for improved error messages based on context.
+
 2017-04-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r215674.
index 6fdaf6a..d49c0b7 100644 (file)
@@ -50,8 +50,8 @@
 #define matchOrFail(tokenType, ...) do { if (!match(tokenType)) { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0)
 #define failIfStackOverflow() do { if (UNLIKELY(!canRecurse())) failWithStackOverflow(); } while (0)
 #define semanticFail(...) do { internalFailWithMessage(false, __VA_ARGS__); } while (0)
-#define semanticFailIfTrue(cond, ...) do { if (cond) internalFailWithMessage(false, __VA_ARGS__); } while (0)
-#define semanticFailIfFalse(cond, ...) do { if (!(cond)) internalFailWithMessage(false, __VA_ARGS__); } while (0)
+#define semanticFailIfTrue(cond, ...) do { if (UNLIKELY(cond)) internalFailWithMessage(false, __VA_ARGS__); } while (0)
+#define semanticFailIfFalse(cond, ...) do { if (UNLIKELY(!(cond))) internalFailWithMessage(false, __VA_ARGS__); } while (0)
 #define regexFail(failure) do { setErrorMessage(failure); return 0; } while (0)
 #define failDueToUnexpectedToken() do {\
         logError(true);\
     consumeOrFail(token, "Expected '", tokenString, "' to ", operation, " an ", production);\
 } while (0)
 
-#define semanticFailureDueToKeyword(...) do { \
-    if (strictMode() && m_token.m_type == RESERVED_IF_STRICT) \
-        semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__, " in strict mode"); \
-    if (m_token.m_type == RESERVED || m_token.m_type == RESERVED_IF_STRICT) \
-        semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__); \
-    if (m_token.m_type & KeywordTokenFlag) \
-        semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \
-    if (isDisallowedIdentifierAwait(m_token)) \
-        semanticFail("Can't use 'await' as a ", __VA_ARGS__, " ", disallowedIdentifierAwaitReason()); \
+#define semanticFailureDueToKeywordCheckingToken(token, ...) do { \
+    if (strictMode() && token.m_type == RESERVED_IF_STRICT) \
+        semanticFail("Cannot use the reserved word '", getToken(token), "' as a ", __VA_ARGS__, " in strict mode"); \
+    if (token.m_type == RESERVED || token.m_type == RESERVED_IF_STRICT) \
+        semanticFail("Cannot use the reserved word '", getToken(token), "' as a ", __VA_ARGS__); \
+    if (token.m_type & KeywordTokenFlag) { \
+        if (!isAnyContextualKeyword(token)) \
+            semanticFail("Cannot use the keyword '", getToken(token), "' as a ", __VA_ARGS__); \
+        if (isDisallowedIdentifierLet(token)) \
+            semanticFail("Cannot use 'let' as a ", __VA_ARGS__, " ", disallowedIdentifierLetReason()); \
+        if (isDisallowedIdentifierAwait(token)) \
+            semanticFail("Cannot use 'await' as a ", __VA_ARGS__, " ", disallowedIdentifierAwaitReason()); \
+        if (isDisallowedIdentifierYield(token)) \
+            semanticFail("Cannot use 'yield' as a ", __VA_ARGS__, " ", disallowedIdentifierYieldReason()); \
+    } \
 } while (0)
 
+#define semanticFailureDueToKeyword(...) semanticFailureDueToKeywordCheckingToken(m_token, __VA_ARGS__);
+
 using namespace std;
 
 namespace JSC {
@@ -704,8 +712,8 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDecl
         bool hasInitializer = false;
         if (matchSpecIdentifier()) {
             failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), 
-                "Can't use 'let' as an identifier name for a LexicalDeclaration");
-            semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", declarationTypeToVariableKind(declarationType), " ", disallowedIdentifierAwaitReason());
+                "Cannot use 'let' as an identifier name for a LexicalDeclaration");
+            semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Cannot use 'await' as a ", declarationTypeToVariableKind(declarationType), " ", disallowedIdentifierAwaitReason());
             JSTextPosition varStart = tokenStartPosition();
             JSTokenLocation varStartLocation(tokenLocation());
             identStart = varStart;
@@ -1030,7 +1038,7 @@ template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
             TreeDestructuringPattern innerPattern = 0;
             JSTokenLocation location = m_token.m_location;
             if (matchSpecIdentifier()) {
-                failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration");
+                failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Cannot use 'let' as an identifier name for a LexicalDeclaration");
                 propertyName = m_token.m_data.ident;
                 JSToken identifierToken = m_token;
                 next();
@@ -1043,7 +1051,7 @@ template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
                             reclassifyExpressionError(ErrorIndicatesPattern, ErrorIndicatesNothing);
                         failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode");
                     }
-                    semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
+                    semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Cannot use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
                     innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier);
                 }
             } else {
@@ -1111,8 +1119,8 @@ template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
             semanticFailureDueToKeyword(destructuringKindToVariableKindName(kind));
             failWithMessage("Expected a parameter pattern or a ')' in parameter list");
         }
-        failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration");
-        semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
+        failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Cannot use 'let' as an identifier name for a LexicalDeclaration");
+        semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Cannot use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
         pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier);
         next();
         break;
@@ -1866,7 +1874,7 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeB
         
         if (match(DOTDOTDOT)) {
             next();
-            semanticFailIfTrue(!m_parserState.allowAwait && match(AWAIT), "Can't use 'await' as a parameter name in an async function");
+            semanticFailIfTrue(!m_parserState.allowAwait && match(AWAIT), "Cannot use 'await' as a parameter name in an async function");
             TreeDestructuringPattern destructuringPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern);
             propagateError();
             parameter = context.createRestParameter(destructuringPattern, restParameterStart);
@@ -2226,6 +2234,8 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
                     semanticFailIfTrue(functionDefinitionType == FunctionDefinitionType::Declaration || isAsyncFunctionWrapperParseMode(mode), "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
                 else if (isAsyncFunctionWrapperParseMode(mode) && match(AWAIT) && functionDefinitionType == FunctionDefinitionType::Expression)
                     semanticFail("Cannot declare async function named 'await'");
+                else if (mode == SourceParseMode::GeneratorWrapperFunctionMode && match(YIELD) && functionDefinitionType == FunctionDefinitionType::Expression)
+                    semanticFail("Cannot declare generator function named 'yield'");
                 next();
                 if (!nameIsInContainingScope)
                     failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
@@ -2771,8 +2781,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
             return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
         }
 
-        if (UNLIKELY(match(AWAIT)))
-            semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a label ", disallowedIdentifierAwaitReason());
+        semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Cannot use 'await' as a label ", disallowedIdentifierAwaitReason());
+        semanticFailIfTrue(isDisallowedIdentifierYield(m_token), "Cannot use 'yield' as a label ", disallowedIdentifierYieldReason());
 
         const Identifier* ident = m_token.m_data.ident;
         JSTextPosition end = tokenEndPosition();
@@ -3688,11 +3698,13 @@ parseProperty:
         isAsync = !isGenerator && !isAsyncMethod;
         FALLTHROUGH;
     case IDENT:
+    case YIELD:
     case AWAIT:
         wasIdent = true;
         FALLTHROUGH;
     case STRING: {
 namedProperty:
+        JSToken identToken = m_token;
         const Identifier* ident = m_token.m_data.ident;
         unsigned getterOrSetterStartOffset = tokenStart();
 
@@ -3720,6 +3732,7 @@ namedProperty:
         failIfFalse(wasIdent, "Expected an identifier as property name");
 
         if (match(COMMA) || match(CLOSEBRACE)) {
+            semanticFailureDueToKeywordCheckingToken(identToken, "shorthand property name");
             JSTextPosition start = tokenStartPosition();
             JSTokenLocation location(tokenLocation());
             currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
index fee1d7b..4f078f3 100644 (file)
@@ -1367,7 +1367,12 @@ private:
     {
         return m_lexer->getToken(m_token);
     }
-    
+
+    ALWAYS_INLINE StringView getToken(const JSToken& token)
+    {
+        return m_lexer->getToken(token);
+    }
+
     ALWAYS_INLINE bool match(JSTokenType expected)
     {
         return m_token.m_type == expected;
@@ -1640,10 +1645,20 @@ private:
         return !m_errorMessage.isNull();
     }
 
+    bool isDisallowedIdentifierLet(const JSToken& token)
+    {
+        return token.m_type == LET && strictMode();
+    }
+
     bool isDisallowedIdentifierAwait(const JSToken& token)
     {
         return token.m_type == AWAIT && (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary() || m_scriptMode == JSParserScriptMode::Module);
     }
+
+    bool isDisallowedIdentifierYield(const JSToken& token)
+    {
+        return token.m_type == YIELD && (strictMode() || currentScope()->isGenerator());
+    }
     
     ALWAYS_INLINE SuperBinding adjustSuperBindingForBaseConstructor(ConstructorKind constructorKind, SuperBinding superBinding, ScopeRef functionScope)
     {
@@ -1662,6 +1677,12 @@ private:
         return methodSuperBinding;
     }
 
+    const char* disallowedIdentifierLetReason()
+    {
+        ASSERT(strictMode());
+        return "in strict mode";
+    }
+
     const char* disallowedIdentifierAwaitReason()
     {
         if (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary())
@@ -1672,6 +1693,16 @@ private:
         return nullptr;
     }
 
+    const char* disallowedIdentifierYieldReason()
+    {
+        if (strictMode())
+            return "in strict mode";
+        if (currentScope()->isGenerator())
+            return "in a generator function";
+        RELEASE_ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+
     enum class FunctionParsePhase { Parameters, Body };
     struct ParserState {
         int assignmentCount { 0 };