Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: test/cctest/test-parsing.cc

Issue 345573002: Infer whether a variable is assigned (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/variables.h ('K') | « src/variables.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-parsing.cc
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 550ac17a060eccc728c6f92cc5c151475e55b4bc..7fddc01657d5cf684f39a27dac30808526c40761 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -37,6 +37,7 @@
#include "src/objects.h"
#include "src/parser.h"
#include "src/preparser.h"
+#include "src/rewriter.h"
#include "src/scanner-character-streams.h"
#include "src/token.h"
#include "src/utils.h"
@@ -2549,3 +2550,108 @@ TEST(FuncNameInferrerEscaped) {
i::DeleteArray(two_byte_source);
i::DeleteArray(two_byte_name);
}
+
+
+TEST(InnerAssignment) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ const char* prefix = "function f() {";
+ const char* midfix = " function g() {";
+ const char* suffix = "}}";
+ struct { const char* source; bool strict; } outers[] = {
+ { "var x;", false },
+ { "var x = 5;", false },
+ { "var x; x = 5;", false },
+ { "var x; var x = 5;", false },
+ { "'use strict'; let x;", true },
+ { "'use strict'; let x = 6;", true },
+ { "'use strict'; let x; x = 6;", true },
+ { "function x() {}", false },
+ };
+ struct { const char* source; bool assigned; } inners[] = {
+ { "x = 1;", true },
+ { "x++;", true },
+ { "++x;", true },
+ { "x--;", true },
+ { "--x;", true },
+ { "{ x = 1; }", true },
+ { "'use strict'; { let x; }; x = 0;", true },
+ { "'use strict'; { const x = 1; }; x = 0;", true },
+ { "'use strict'; { function x() {} }; x = 0;", true },
+ { "with ({}) { x = 1; }", true },
+ { "eval('');", true },
+ { "'use strict'; { let y; eval('') }", true },
+ { "function h() { x = 0; }", true },
+ { "(function() { x = 0; })", true },
+ { "(function() { x = 0; })", true },
+ { "with ({}) (function() { x = 0; })", true },
+ { "", false },
+ { "x;", false },
+ { "var x;", false },
+ { "var x = 8;", false },
+ { "var x; x = 8;", false },
+ { "'use strict'; let x;", false },
+ { "'use strict'; let x = 8;", false },
+ { "'use strict'; let x; x = 8;", false },
+ { "'use strict'; const x = 8;", false },
+ { "function x() {}", false },
+ { "function x() { x = 0; }", false },
+ { "'use strict'; { let x; x = 0; }", false },
+ { "{ var x; }; x = 0;", false },
+ { "with ({}) {}", false },
+ { "var x; { with ({}) { x = 1; } }", false },
+ { "try {} catch(x) { x = 0; }", false },
+ { "try {} catch(x) { with ({}) { x = 1; } }", false },
+ // For simplicity, eval unconditionally sets flag to true.
+ { "var x; { eval('') }", true },
+ { "'use strict'; let x; { eval('') }", true },
+ { "'use strict'; { let x; eval('') }", true },
+ { "try {} catch(x) { eval(''); }", true },
+ };
+ i::Handle<i::String> var_name =
+ factory->NewStringFromUtf8(i::CStrVector("x")).ToHandleChecked();
titzer 2014/06/23 13:03:19 factory->InternalizeUtf8String()?
rossberg 2014/06/24 13:40:43 Done (also below).
+
+ int prefix_len = Utf8LengthHelper(prefix);
+ int midfix_len = Utf8LengthHelper(midfix);
+ int suffix_len = Utf8LengthHelper(suffix);
+ for (unsigned i = 0; i < ARRAY_SIZE(outers); ++i) {
+ const char* outer = outers[i].source;
+ int outer_len = Utf8LengthHelper(outer);
+ for (unsigned j = 0; j < ARRAY_SIZE(inners); ++j) {
+ const char* inner = inners[j].source;
+ int inner_len = Utf8LengthHelper(inner);
+ int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len;
+ i::ScopedVector<char> program(len + 1);
+ i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner, suffix);
+ i::Handle<i::String> source = factory->NewStringFromUtf8(
+ i::CStrVector(program.start())).ToHandleChecked();
+
+ i::Handle<i::Script> script = factory->NewScript(source);
+ i::CompilationInfoWithZone info(script);
+ i::Parser parser(&info);
+ parser.set_allow_harmony_scoping(true);
+ if (!parser.Parse()) {
+ // Some combinations (strict + with) cause static errors, ignore.
+ ASSERT(outers[i].strict);
+ printf("Skipping ");
+ source->Print();
+ printf("\n");
+ continue;
+ }
+ CHECK(i::Rewriter::Rewrite(&info));
+ CHECK(i::Scope::Analyze(&info));
+ CHECK(info.function() != NULL);
+
+ i::Scope* scope = info.function()->scope();
+ CHECK_EQ(scope->inner_scopes()->length(), 1);
+ i::Scope* inner_scope = scope->inner_scopes()->at(0);
+ i::Variable* var = inner_scope->Lookup(var_name);
+ CHECK(var != NULL);
+ CHECK(var->is_used() || !inners[j].assigned);
+ CHECK(var->is_assigned_in_inner_function() == inners[j].assigned);
+ }
+ }
+}
« src/variables.h ('K') | « src/variables.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698