| Index: test/cctest/test-parsing.cc
|
| diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
|
| index 9a4904652e36df72295792e581db9b417ab688d5..00b07328e588e2e19847022cb92cf4e9c6015c87 100644
|
| --- a/test/cctest/test-parsing.cc
|
| +++ b/test/cctest/test-parsing.cc
|
| @@ -3492,6 +3492,365 @@
|
| bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
|
| CHECK_EQ(is_maybe_assigned, assigned);
|
| }
|
| + }
|
| +}
|
| +
|
| +struct Input {
|
| + bool assigned;
|
| + std::string source;
|
| + std::vector<unsigned> location; // "Directions" to the relevant scope.
|
| +};
|
| +
|
| +static void TestMaybeAssigned(i::Zone* zone, Input input, const char* variable,
|
| + bool module, bool allow_lazy_parsing) {
|
| + i::Factory* factory = CcTest::i_isolate()->factory();
|
| + i::Handle<i::String> string =
|
| + factory->InternalizeUtf8String(input.source.c_str());
|
| + string->PrintOn(stdout);
|
| + printf("\n");
|
| + i::Handle<i::Script> script = factory->NewScript(string);
|
| +
|
| + std::unique_ptr<i::ParseInfo> info;
|
| + info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(zone, script));
|
| + info->set_module(module);
|
| + info->set_allow_lazy_parsing(allow_lazy_parsing);
|
| +
|
| + CHECK(i::parsing::ParseProgram(info.get()));
|
| + CHECK(i::Compiler::Analyze(info.get()));
|
| +
|
| + CHECK_NOT_NULL(info->literal());
|
| + i::Scope* scope = info->literal()->scope();
|
| + CHECK(!scope->AsDeclarationScope()->was_lazily_parsed());
|
| + CHECK_NULL(scope->sibling());
|
| + CHECK(module ? scope->is_module_scope() : scope->is_script_scope());
|
| +
|
| + i::Variable* var;
|
| + {
|
| + // Find the variable.
|
| + for (auto it = input.location.begin(); it != input.location.end(); ++it) {
|
| + unsigned n = *it;
|
| + scope = scope->inner_scope();
|
| + while (n-- > 0) {
|
| + scope = scope->sibling();
|
| + }
|
| + }
|
| + CHECK_NOT_NULL(scope);
|
| + const i::AstRawString* var_name =
|
| + info->ast_value_factory()->GetOneByteString(variable);
|
| + var = scope->Lookup(var_name);
|
| + }
|
| +
|
| + CHECK(var->is_used());
|
| + STATIC_ASSERT(true == i::kMaybeAssigned);
|
| + CHECK_EQ(input.assigned, var->maybe_assigned() == i::kMaybeAssigned);
|
| +}
|
| +
|
| +static Input wrap(Input input) {
|
| + Input result;
|
| + result.assigned = input.assigned;
|
| + result.source = "function WRAPPED() { " + input.source + " }";
|
| + result.location.push_back(0);
|
| + for (auto n : input.location) {
|
| + result.location.push_back(n);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +TEST(MaybeAssignedInsideLoop) {
|
| + i::Isolate* isolate = CcTest::i_isolate();
|
| + i::HandleScope scope(isolate);
|
| + LocalContext env;
|
| + i::Zone zone(isolate->allocator(), ZONE_NAME);
|
| +
|
| + std::vector<unsigned> top; // Can't use {} in initializers below.
|
| +
|
| + Input module_and_script_tests[] = {
|
| + {1, "for (j=x; j<10; ++j) { foo = j }", top},
|
| + {1, "for (j=x; j<10; ++j) { [foo] = [j] }", top},
|
| + {1, "for (j=x; j<10; ++j) { var foo = j }", top},
|
| + {1, "for (j=x; j<10; ++j) { var [foo] = [j] }", top},
|
| + {0, "for (j=x; j<10; ++j) { let foo = j }", {0}},
|
| + {0, "for (j=x; j<10; ++j) { let [foo] = [j] }", {0}},
|
| + {0, "for (j=x; j<10; ++j) { const foo = j }", {0}},
|
| + {0, "for (j=x; j<10; ++j) { const [foo] = [j] }", {0}},
|
| + {0, "for (j=x; j<10; ++j) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for ({j}=x; j<10; ++j) { foo = j }", top},
|
| + {1, "for ({j}=x; j<10; ++j) { [foo] = [j] }", top},
|
| + {1, "for ({j}=x; j<10; ++j) { var foo = j }", top},
|
| + {1, "for ({j}=x; j<10; ++j) { var [foo] = [j] }", top},
|
| + {0, "for ({j}=x; j<10; ++j) { let foo = j }", {0}},
|
| + {0, "for ({j}=x; j<10; ++j) { let [foo] = [j] }", {0}},
|
| + {0, "for ({j}=x; j<10; ++j) { const foo = j }", {0}},
|
| + {0, "for ({j}=x; j<10; ++j) { const [foo] = [j] }", {0}},
|
| + {0, "for ({j}=x; j<10; ++j) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (var j=x; j<10; ++j) { foo = j }", top},
|
| + {1, "for (var j=x; j<10; ++j) { [foo] = [j] }", top},
|
| + {1, "for (var j=x; j<10; ++j) { var foo = j }", top},
|
| + {1, "for (var j=x; j<10; ++j) { var [foo] = [j] }", top},
|
| + {0, "for (var j=x; j<10; ++j) { let foo = j }", {0}},
|
| + {0, "for (var j=x; j<10; ++j) { let [foo] = [j] }", {0}},
|
| + {0, "for (var j=x; j<10; ++j) { const foo = j }", {0}},
|
| + {0, "for (var j=x; j<10; ++j) { const [foo] = [j] }", {0}},
|
| + {0, "for (var j=x; j<10; ++j) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (var {j}=x; j<10; ++j) { foo = j }", top},
|
| + {1, "for (var {j}=x; j<10; ++j) { [foo] = [j] }", top},
|
| + {1, "for (var {j}=x; j<10; ++j) { var foo = j }", top},
|
| + {1, "for (var {j}=x; j<10; ++j) { var [foo] = [j] }", top},
|
| + {0, "for (var {j}=x; j<10; ++j) { let foo = j }", {0}},
|
| + {0, "for (var {j}=x; j<10; ++j) { let [foo] = [j] }", {0}},
|
| + {0, "for (var {j}=x; j<10; ++j) { const foo = j }", {0}},
|
| + {0, "for (var {j}=x; j<10; ++j) { const [foo] = [j] }", {0}},
|
| + {0, "for (var {j}=x; j<10; ++j) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (let j=x; j<10; ++j) { foo = j }", top},
|
| + {1, "for (let j=x; j<10; ++j) { [foo] = [j] }", top},
|
| + {1, "for (let j=x; j<10; ++j) { var foo = j }", top},
|
| + {1, "for (let j=x; j<10; ++j) { var [foo] = [j] }", top},
|
| + {0, "for (let j=x; j<10; ++j) { let foo = j }", {0, 0, 0}},
|
| + {0, "for (let j=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0, 0}},
|
| + {0, "for (let j=x; j<10; ++j) { const [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let j=x; j<10; ++j) { function foo() {return j} }", {0, 0, 0}},
|
| +
|
| + {1, "for (let {j}=x; j<10; ++j) { foo = j }", top},
|
| + {1, "for (let {j}=x; j<10; ++j) { [foo] = [j] }", top},
|
| + {1, "for (let {j}=x; j<10; ++j) { var foo = j }", top},
|
| + {1, "for (let {j}=x; j<10; ++j) { var [foo] = [j] }", top},
|
| + {0, "for (let {j}=x; j<10; ++j) { let foo = j }", {0, 0, 0}},
|
| + {0, "for (let {j}=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0, 0}},
|
| + {0, "for (let {j}=x; j<10; ++j) { const [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let {j}=x; j<10; ++j) { function foo(){return j} }", {0, 0, 0}},
|
| +
|
| + {1, "for (j of x) { foo = j }", top},
|
| + {1, "for (j of x) { [foo] = [j] }", top},
|
| + {1, "for (j of x) { var foo = j }", top},
|
| + {1, "for (j of x) { var [foo] = [j] }", top},
|
| + {0, "for (j of x) { let foo = j }", {0}},
|
| + {0, "for (j of x) { let [foo] = [j] }", {0}},
|
| + {0, "for (j of x) { const foo = j }", {0}},
|
| + {0, "for (j of x) { const [foo] = [j] }", {0}},
|
| + {0, "for (j of x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for ({j} of x) { foo = j }", top},
|
| + {1, "for ({j} of x) { [foo] = [j] }", top},
|
| + {1, "for ({j} of x) { var foo = j }", top},
|
| + {1, "for ({j} of x) { var [foo] = [j] }", top},
|
| + {0, "for ({j} of x) { let foo = j }", {0}},
|
| + {0, "for ({j} of x) { let [foo] = [j] }", {0}},
|
| + {0, "for ({j} of x) { const foo = j }", {0}},
|
| + {0, "for ({j} of x) { const [foo] = [j] }", {0}},
|
| + {0, "for ({j} of x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (var j of x) { foo = j }", top},
|
| + {1, "for (var j of x) { [foo] = [j] }", top},
|
| + {1, "for (var j of x) { var foo = j }", top},
|
| + {1, "for (var j of x) { var [foo] = [j] }", top},
|
| + {0, "for (var j of x) { let foo = j }", {0}},
|
| + {0, "for (var j of x) { let [foo] = [j] }", {0}},
|
| + {0, "for (var j of x) { const foo = j }", {0}},
|
| + {0, "for (var j of x) { const [foo] = [j] }", {0}},
|
| + {0, "for (var j of x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (var {j} of x) { foo = j }", top},
|
| + {1, "for (var {j} of x) { [foo] = [j] }", top},
|
| + {1, "for (var {j} of x) { var foo = j }", top},
|
| + {1, "for (var {j} of x) { var [foo] = [j] }", top},
|
| + {0, "for (var {j} of x) { let foo = j }", {0}},
|
| + {0, "for (var {j} of x) { let [foo] = [j] }", {0}},
|
| + {0, "for (var {j} of x) { const foo = j }", {0}},
|
| + {0, "for (var {j} of x) { const [foo] = [j] }", {0}},
|
| + {0, "for (var {j} of x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (let j of x) { foo = j }", top},
|
| + {1, "for (let j of x) { [foo] = [j] }", top},
|
| + {1, "for (let j of x) { var foo = j }", top},
|
| + {1, "for (let j of x) { var [foo] = [j] }", top},
|
| + {0, "for (let j of x) { let foo = j }", {0, 2, 0}},
|
| + {0, "for (let j of x) { let [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (let j of x) { const foo = j }", {0, 2, 0}},
|
| + {0, "for (let j of x) { const [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (let j of x) { function foo() {return j} }", {0, 2, 0}},
|
| +
|
| + {1, "for (let {j} of x) { foo = j }", top},
|
| + {1, "for (let {j} of x) { [foo] = [j] }", top},
|
| + {1, "for (let {j} of x) { var foo = j }", top},
|
| + {1, "for (let {j} of x) { var [foo] = [j] }", top},
|
| + {0, "for (let {j} of x) { let foo = j }", {0, 2, 0}},
|
| + {0, "for (let {j} of x) { let [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (let {j} of x) { const foo = j }", {0, 2, 0}},
|
| + {0, "for (let {j} of x) { const [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (let {j} of x) { function foo() {return j} }", {0, 2, 0}},
|
| +
|
| + {1, "for (const j of x) { foo = j }", top},
|
| + {1, "for (const j of x) { [foo] = [j] }", top},
|
| + {1, "for (const j of x) { var foo = j }", top},
|
| + {1, "for (const j of x) { var [foo] = [j] }", top},
|
| + {0, "for (const j of x) { let foo = j }", {0, 2, 0}},
|
| + {0, "for (const j of x) { let [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (const j of x) { const foo = j }", {0, 2, 0}},
|
| + {0, "for (const j of x) { const [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (const j of x) { function foo() {return j} }", {0, 2, 0}},
|
| +
|
| + {1, "for (const {j} of x) { foo = j }", top},
|
| + {1, "for (const {j} of x) { [foo] = [j] }", top},
|
| + {1, "for (const {j} of x) { var foo = j }", top},
|
| + {1, "for (const {j} of x) { var [foo] = [j] }", top},
|
| + {0, "for (const {j} of x) { let foo = j }", {0, 2, 0}},
|
| + {0, "for (const {j} of x) { let [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (const {j} of x) { const foo = j }", {0, 2, 0}},
|
| + {0, "for (const {j} of x) { const [foo] = [j] }", {0, 2, 0}},
|
| + {0, "for (const {j} of x) { function foo() {return j} }", {0, 2, 0}},
|
| +
|
| + {1, "for (j in x) { foo = j }", top},
|
| + {1, "for (j in x) { [foo] = [j] }", top},
|
| + {1, "for (j in x) { var foo = j }", top},
|
| + {1, "for (j in x) { var [foo] = [j] }", top},
|
| + {0, "for (j in x) { let foo = j }", {0}},
|
| + {0, "for (j in x) { let [foo] = [j] }", {0}},
|
| + {0, "for (j in x) { const foo = j }", {0}},
|
| + {0, "for (j in x) { const [foo] = [j] }", {0}},
|
| + {0, "for (j in x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for ({j} in x) { foo = j }", top},
|
| + {1, "for ({j} in x) { [foo] = [j] }", top},
|
| + {1, "for ({j} in x) { var foo = j }", top},
|
| + {1, "for ({j} in x) { var [foo] = [j] }", top},
|
| + {0, "for ({j} in x) { let foo = j }", {0}},
|
| + {0, "for ({j} in x) { let [foo] = [j] }", {0}},
|
| + {0, "for ({j} in x) { const foo = j }", {0}},
|
| + {0, "for ({j} in x) { const [foo] = [j] }", {0}},
|
| + {0, "for ({j} in x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (var j in x) { foo = j }", top},
|
| + {1, "for (var j in x) { [foo] = [j] }", top},
|
| + {1, "for (var j in x) { var foo = j }", top},
|
| + {1, "for (var j in x) { var [foo] = [j] }", top},
|
| + {0, "for (var j in x) { let foo = j }", {0}},
|
| + {0, "for (var j in x) { let [foo] = [j] }", {0}},
|
| + {0, "for (var j in x) { const foo = j }", {0}},
|
| + {0, "for (var j in x) { const [foo] = [j] }", {0}},
|
| + {0, "for (var j in x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (var {j} in x) { foo = j }", top},
|
| + {1, "for (var {j} in x) { [foo] = [j] }", top},
|
| + {1, "for (var {j} in x) { var foo = j }", top},
|
| + {1, "for (var {j} in x) { var [foo] = [j] }", top},
|
| + {0, "for (var {j} in x) { let foo = j }", {0}},
|
| + {0, "for (var {j} in x) { let [foo] = [j] }", {0}},
|
| + {0, "for (var {j} in x) { const foo = j }", {0}},
|
| + {0, "for (var {j} in x) { const [foo] = [j] }", {0}},
|
| + {0, "for (var {j} in x) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "for (let j in x) { foo = j }", top},
|
| + {1, "for (let j in x) { [foo] = [j] }", top},
|
| + {1, "for (let j in x) { var foo = j }", top},
|
| + {1, "for (let j in x) { var [foo] = [j] }", top},
|
| + {0, "for (let j in x) { let foo = j }", {0, 0, 0}},
|
| + {0, "for (let j in x) { let [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let j in x) { const foo = j }", {0, 0, 0}},
|
| + {0, "for (let j in x) { const [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let j in x) { function foo() {return j} }", {0, 0, 0}},
|
| +
|
| + {1, "for (let {j} in x) { foo = j }", top},
|
| + {1, "for (let {j} in x) { [foo] = [j] }", top},
|
| + {1, "for (let {j} in x) { var foo = j }", top},
|
| + {1, "for (let {j} in x) { var [foo] = [j] }", top},
|
| + {0, "for (let {j} in x) { let foo = j }", {0, 0, 0}},
|
| + {0, "for (let {j} in x) { let [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let {j} in x) { const foo = j }", {0, 0, 0}},
|
| + {0, "for (let {j} in x) { const [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (let {j} in x) { function foo() {return j} }", {0, 0, 0}},
|
| +
|
| + {1, "for (const j in x) { foo = j }", top},
|
| + {1, "for (const j in x) { [foo] = [j] }", top},
|
| + {1, "for (const j in x) { var foo = j }", top},
|
| + {1, "for (const j in x) { var [foo] = [j] }", top},
|
| + {0, "for (const j in x) { let foo = j }", {0, 0, 0}},
|
| + {0, "for (const j in x) { let [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (const j in x) { const foo = j }", {0, 0, 0}},
|
| + {0, "for (const j in x) { const [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (const j in x) { function foo() {return j} }", {0, 0, 0}},
|
| +
|
| + {1, "for (const {j} in x) { foo = j }", top},
|
| + {1, "for (const {j} in x) { [foo] = [j] }", top},
|
| + {1, "for (const {j} in x) { var foo = j }", top},
|
| + {1, "for (const {j} in x) { var [foo] = [j] }", top},
|
| + {0, "for (const {j} in x) { let foo = j }", {0, 0, 0}},
|
| + {0, "for (const {j} in x) { let [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (const {j} in x) { const foo = j }", {0, 0, 0}},
|
| + {0, "for (const {j} in x) { const [foo] = [j] }", {0, 0, 0}},
|
| + {0, "for (const {j} in x) { function foo() {return j} }", {0, 0, 0}},
|
| +
|
| + {1, "while (j) { foo = j }", top},
|
| + {1, "while (j) { [foo] = [j] }", top},
|
| + {1, "while (j) { var foo = j }", top},
|
| + {1, "while (j) { var [foo] = [j] }", top},
|
| + {0, "while (j) { let foo = j }", {0}},
|
| + {0, "while (j) { let [foo] = [j] }", {0}},
|
| + {0, "while (j) { const foo = j }", {0}},
|
| + {0, "while (j) { const [foo] = [j] }", {0}},
|
| + {0, "while (j) { function foo() {return j} }", {0}},
|
| +
|
| + {1, "do { foo = j } while (j)", top},
|
| + {1, "do { [foo] = [j] } while (j)", top},
|
| + {1, "do { var foo = j } while (j)", top},
|
| + {1, "do { var [foo] = [j] } while (j)", top},
|
| + {0, "do { let foo = j } while (j)", {0}},
|
| + {0, "do { let [foo] = [j] } while (j)", {0}},
|
| + {0, "do { const foo = j } while (j)", {0}},
|
| + {0, "do { const [foo] = [j] } while (j)", {0}},
|
| + {0, "do { function foo() {return j} } while (j)", {0}},
|
| + };
|
| +
|
| + Input script_only_tests[] = {
|
| + {1, "for (j=x; j<10; ++j) { function foo() {return j} }", top},
|
| + {1, "for ({j}=x; j<10; ++j) { function foo() {return j} }", top},
|
| + {1, "for (var j=x; j<10; ++j) { function foo() {return j} }", top},
|
| + {1, "for (var {j}=x; j<10; ++j) { function foo() {return j} }", top},
|
| + {1, "for (let j=x; j<10; ++j) { function foo() {return j} }", top},
|
| + {1, "for (let {j}=x; j<10; ++j) { function foo() {return j} }", top},
|
| + {1, "for (j of x) { function foo() {return j} }", top},
|
| + {1, "for ({j} of x) { function foo() {return j} }", top},
|
| + {1, "for (var j of x) { function foo() {return j} }", top},
|
| + {1, "for (var {j} of x) { function foo() {return j} }", top},
|
| + {1, "for (let j of x) { function foo() {return j} }", top},
|
| + {1, "for (let {j} of x) { function foo() {return j} }", top},
|
| + {1, "for (const j of x) { function foo() {return j} }", top},
|
| + {1, "for (const {j} of x) { function foo() {return j} }", top},
|
| + {1, "for (j in x) { function foo() {return j} }", top},
|
| + {1, "for ({j} in x) { function foo() {return j} }", top},
|
| + {1, "for (var j in x) { function foo() {return j} }", top},
|
| + {1, "for (var {j} in x) { function foo() {return j} }", top},
|
| + {1, "for (let j in x) { function foo() {return j} }", top},
|
| + {1, "for (let {j} in x) { function foo() {return j} }", top},
|
| + {1, "for (const j in x) { function foo() {return j} }", top},
|
| + {1, "for (const {j} in x) { function foo() {return j} }", top},
|
| + {1, "while (j) { function foo() {return j} }", top},
|
| + {1, "do { function foo() {return j} } while (j)", top},
|
| + };
|
| +
|
| + for (unsigned i = 0; i < arraysize(module_and_script_tests); ++i) {
|
| + Input input = module_and_script_tests[i];
|
| + for (unsigned module = 0; module <= 1; ++module) {
|
| + for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
|
| + ++allow_lazy_parsing) {
|
| + TestMaybeAssigned(&zone, input, "foo", module, allow_lazy_parsing);
|
| + }
|
| + TestMaybeAssigned(&zone, wrap(input), "foo", module, false);
|
| + }
|
| + }
|
| +
|
| + for (unsigned i = 0; i < arraysize(script_only_tests); ++i) {
|
| + Input input = script_only_tests[i];
|
| + for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
|
| + ++allow_lazy_parsing) {
|
| + TestMaybeAssigned(&zone, input, "foo", false, allow_lazy_parsing);
|
| + }
|
| + TestMaybeAssigned(&zone, wrap(input), "foo", false, false);
|
| }
|
| }
|
|
|
|
|