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

Side by Side 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: A few more tests 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/variables.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 19 matching lines...) Expand all
30 #include <string.h> 30 #include <string.h>
31 31
32 #include "src/v8.h" 32 #include "src/v8.h"
33 33
34 #include "src/compiler.h" 34 #include "src/compiler.h"
35 #include "src/execution.h" 35 #include "src/execution.h"
36 #include "src/isolate.h" 36 #include "src/isolate.h"
37 #include "src/objects.h" 37 #include "src/objects.h"
38 #include "src/parser.h" 38 #include "src/parser.h"
39 #include "src/preparser.h" 39 #include "src/preparser.h"
40 #include "src/rewriter.h"
40 #include "src/scanner-character-streams.h" 41 #include "src/scanner-character-streams.h"
41 #include "src/token.h" 42 #include "src/token.h"
42 #include "src/utils.h" 43 #include "src/utils.h"
43 #include "test/cctest/cctest.h" 44 #include "test/cctest/cctest.h"
44 45
45 TEST(ScanKeywords) { 46 TEST(ScanKeywords) {
46 struct KeywordToken { 47 struct KeywordToken {
47 const char* keyword; 48 const char* keyword;
48 i::Token::Value token; 49 i::Token::Value token;
49 }; 50 };
(...skipping 2492 matching lines...) Expand 10 before | Expand all | Expand 10 after
2542 v8::Local<v8::String> source = 2543 v8::Local<v8::String> source =
2543 v8::String::NewFromTwoByte(isolate, two_byte_source); 2544 v8::String::NewFromTwoByte(isolate, two_byte_source);
2544 v8::Local<v8::Value> result = CompileRun(source); 2545 v8::Local<v8::Value> result = CompileRun(source);
2545 CHECK(result->IsString()); 2546 CHECK(result->IsString());
2546 v8::Local<v8::String> expected_name = 2547 v8::Local<v8::String> expected_name =
2547 v8::String::NewFromTwoByte(isolate, two_byte_name); 2548 v8::String::NewFromTwoByte(isolate, two_byte_name);
2548 CHECK(result->Equals(expected_name)); 2549 CHECK(result->Equals(expected_name));
2549 i::DeleteArray(two_byte_source); 2550 i::DeleteArray(two_byte_source);
2550 i::DeleteArray(two_byte_name); 2551 i::DeleteArray(two_byte_name);
2551 } 2552 }
2553
2554
2555 TEST(InnerAssignment) {
2556 i::Isolate* isolate = CcTest::i_isolate();
2557 i::Factory* factory = isolate->factory();
2558 i::HandleScope scope(isolate);
2559 LocalContext env;
2560
2561 const char* prefix = "function f() {";
2562 const char* midfix = " function g() {";
2563 const char* suffix = "}}";
2564 struct { const char* source; bool assigned; bool strict; } outers[] = {
2565 // Actual assignments.
2566 { "var x; var x = 5;", true, false },
2567 { "var x; { var x = 5; }", true, false },
2568 { "'use strict'; let x; x = 6;", true, true },
2569 // Actual non-assignments.
2570 { "var x;", false, false },
2571 { "var x = 5;", false, false },
2572 { "'use strict'; let x;", false, true },
2573 { "'use strict'; let x = 6;", false, true },
2574 { "'use strict'; var x = 0; { let x = 6; }", false, true },
2575 { "'use strict'; var x = 0; { let x; x = 6; }", false, true },
2576 { "'use strict'; let x = 0; { let x = 6; }", false, true },
2577 { "'use strict'; let x = 0; { let x; x = 6; }", false, true },
2578 { "var x; try {} catch (x) { x = 5; }", false, false },
2579 { "function x() {}", false, false },
2580 // Eval approximation.
2581 { "var x; eval('');", true, false },
2582 { "eval(''); var x;", true, false },
2583 { "'use strict'; let x; eval('');", true, true },
2584 { "'use strict'; eval(''); let x;", true, true },
2585 // Non-assignments not recognized, because the analysis is approximative.
2586 { "var x; var x;", true, false },
2587 { "var x = 5; var x;", true, false },
2588 { "var x; { var x; }", true, false },
2589 { "var x; function x() {}", true, false },
2590 { "function x() {}; var x;", true, false },
2591 { "var x; try {} catch (x) { var x = 5; }", true, false },
2592 };
2593 struct { const char* source; bool assigned; bool with; } inners[] = {
2594 // Actual assignments.
2595 { "x = 1;", true, false },
2596 { "x++;", true, false },
2597 { "++x;", true, false },
2598 { "x--;", true, false },
2599 { "--x;", true, false },
2600 { "{ x = 1; }", true, false },
2601 { "'use strict'; { let x; }; x = 0;", true, false },
2602 { "'use strict'; { const x = 1; }; x = 0;", true, false },
2603 { "'use strict'; { function x() {} }; x = 0;", true, false },
2604 { "with ({}) { x = 1; }", true, true },
2605 { "eval('');", true, false },
2606 { "'use strict'; { let y; eval('') }", true, false },
2607 { "function h() { x = 0; }", true, false },
2608 { "(function() { x = 0; })", true, false },
2609 { "(function() { x = 0; })", true, false },
2610 { "with ({}) (function() { x = 0; })", true, true },
2611 // Actual non-assignments.
2612 { "", false, false },
2613 { "x;", false, false },
2614 { "var x;", false, false },
2615 { "var x = 8;", false, false },
2616 { "var x; x = 8;", false, false },
2617 { "'use strict'; let x;", false, false },
2618 { "'use strict'; let x = 8;", false, false },
2619 { "'use strict'; let x; x = 8;", false, false },
2620 { "'use strict'; const x = 8;", false, false },
2621 { "function x() {}", false, false },
2622 { "function x() { x = 0; }", false, false },
2623 { "function h(x) { x = 0; }", false, false },
2624 { "'use strict'; { let x; x = 0; }", false, false },
2625 { "{ var x; }; x = 0;", false, false },
2626 { "with ({}) {}", false, true },
2627 { "var x; { with ({}) { x = 1; } }", false, true },
2628 { "try {} catch(x) { x = 0; }", false, false },
2629 { "try {} catch(x) { with ({}) { x = 1; } }", false, true },
2630 // Eval approximation.
2631 { "eval('');", true, false },
2632 { "function h() { eval(''); }", true, false },
2633 { "(function() { eval(''); })", true, false },
2634 // Shadowing not recognized because of eval approximation.
2635 { "var x; eval('');", true, false },
2636 { "'use strict'; let x; eval('');", true, false },
2637 { "try {} catch(x) { eval(''); }", true, false },
2638 { "function x() { eval(''); }", true, false },
2639 { "(function(x) { eval(''); })", true, false },
2640 };
2641 i::Handle<i::String> var_name = factory->InternalizeUtf8String("x");
2642
2643 int prefix_len = Utf8LengthHelper(prefix);
2644 int midfix_len = Utf8LengthHelper(midfix);
2645 int suffix_len = Utf8LengthHelper(suffix);
2646 for (unsigned i = 0; i < ARRAY_SIZE(outers); ++i) {
2647 const char* outer = outers[i].source;
2648 int outer_len = Utf8LengthHelper(outer);
2649 for (unsigned j = 0; j < ARRAY_SIZE(inners); ++j) {
2650 if (outers[i].strict && inners[j].with) continue;
2651 const char* inner = inners[j].source;
2652 int inner_len = Utf8LengthHelper(inner);
2653 int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len;
2654 i::ScopedVector<char> program(len + 1);
2655 i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner, suffix);
2656 i::Handle<i::String> source =
2657 factory->InternalizeUtf8String(program.start());
2658 source->PrintOn(stdout);
2659 printf("\n");
2660
2661 i::Handle<i::Script> script = factory->NewScript(source);
2662 i::CompilationInfoWithZone info(script);
2663 i::Parser parser(&info);
2664 parser.set_allow_harmony_scoping(true);
2665 CHECK(parser.Parse());
2666 CHECK(i::Rewriter::Rewrite(&info));
2667 CHECK(i::Scope::Analyze(&info));
2668 CHECK(info.function() != NULL);
2669
2670 i::Scope* scope = info.function()->scope();
2671 CHECK_EQ(scope->inner_scopes()->length(), 1);
2672 i::Scope* inner_scope = scope->inner_scopes()->at(0);
2673 i::Variable* var = inner_scope->Lookup(var_name);
2674 bool expected = outers[i].assigned || inners[j].assigned;
2675 CHECK(var != NULL);
2676 CHECK(var->is_used() || !expected);
2677 CHECK(var->maybe_assigned() == expected);
2678 }
2679 }
2680 }
OLDNEW
« no previous file with comments | « src/variables.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698