|  | // Copyright 2020 the V8 project authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // Will be used in the tests | 
|  | function foo() {} | 
|  |  | 
|  | function wrapInLazyFunction(s) { | 
|  | // Use an async function, since some tests use the await keyword. | 
|  | return "async function test() { " + s + "}"; | 
|  | } | 
|  |  | 
|  | function wrapInEagerFunction(s) { | 
|  | // Use an async function, since some tests use the await keyword. Await the | 
|  | // result, so that we get the error right away. | 
|  | return "await (async function test() { " + s + "})();"; | 
|  | } | 
|  |  | 
|  | function assertEarlyError(s) { | 
|  | assertThrows(wrapInLazyFunction(s), SyntaxError); | 
|  | } | 
|  |  | 
|  | function assertLateError(s) { | 
|  | assertDoesNotThrow(wrapInLazyFunction(s)); | 
|  | assertThrows(wrapInEagerFunction(s), ReferenceError); | 
|  | } | 
|  |  | 
|  | // Web compatibility: | 
|  | assertLateError("foo() = 0;"); | 
|  | assertLateError("foo()++;"); | 
|  | assertLateError("foo()--;"); | 
|  | assertLateError("++foo();"); | 
|  | assertLateError("--foo();"); | 
|  | assertLateError("foo() = 1;"); | 
|  | assertLateError("foo() += 1;"); | 
|  | assertLateError("foo() -= 1;"); | 
|  | assertLateError("foo() *= 1;"); | 
|  | assertLateError("foo() /= 1;"); | 
|  | assertLateError("for (foo() = 0; ; ) {}"); | 
|  | assertLateError("for ( ; ; foo() = 0) {}"); | 
|  | assertLateError("for (foo() of []) {}"); | 
|  | assertLateError("for (foo() in {}) {}"); | 
|  | assertLateError("for await (foo() of []) {}"); | 
|  |  | 
|  | // These are early errors though: | 
|  | assertEarlyError("for (let foo() = 0; ;) {}"); | 
|  | assertEarlyError("for (const foo() = 0; ;) {}"); | 
|  | assertEarlyError("for (var foo() = 0; ;) {}"); | 
|  |  | 
|  | // Modern language features: | 
|  | // Tagged templates | 
|  | assertEarlyError("foo() `foo` ++;"); | 
|  | assertEarlyError("foo() `foo` --;"); | 
|  | assertEarlyError("++ foo() `foo`;"); | 
|  | assertEarlyError("-- foo() `foo`;"); | 
|  | assertEarlyError("foo() `foo` = 1;"); | 
|  | assertEarlyError("foo() `foo` += 1;"); | 
|  | assertEarlyError("foo() `foo` -= 1;"); | 
|  | assertEarlyError("foo() `foo` *= 1;"); | 
|  | assertEarlyError("foo() `foo` /= 1;"); | 
|  | assertEarlyError("for (foo() `foo` = 0; ; ) {}"); | 
|  | assertEarlyError("for (; ; foo() `foo` = 0) {}"); | 
|  |  | 
|  | // Logical assignment | 
|  | assertEarlyError("foo() &&= 1;"); | 
|  | assertEarlyError("foo() ||= 1;"); | 
|  | assertEarlyError("foo() ??= 1;"); | 
|  | assertEarlyError("for (foo() &&= 0; ;) {}"); | 
|  | assertEarlyError("for ( ; ; foo() &&= 0) {}"); |