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

Side by Side Diff: src/rewriter.cc

Issue 1361403003: Implement ES6 completion semantics (--harmony-completion). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « src/parser.cc ('k') | test/mjsunit/harmony/completion.js » ('j') | 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/rewriter.h" 5 #include "src/rewriter.h"
6 6
7 #include "src/ast.h" 7 #include "src/ast.h"
8 #include "src/parser.h" 8 #include "src/parser.h"
9 #include "src/scopes.h" 9 #include "src/scopes.h"
10 10
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 bool is_set_; 42 bool is_set_;
43 43
44 AstNodeFactory factory_; 44 AstNodeFactory factory_;
45 45
46 Expression* SetResult(Expression* value) { 46 Expression* SetResult(Expression* value) {
47 VariableProxy* result_proxy = factory()->NewVariableProxy(result_); 47 VariableProxy* result_proxy = factory()->NewVariableProxy(result_);
48 return factory()->NewAssignment( 48 return factory()->NewAssignment(
49 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition); 49 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition);
50 } 50 }
51 51
52 // Inserts '.result = undefined' in front of the given statement.
53 Statement* AssignUndefinedBefore(Statement* s);
54
52 // Node visitors. 55 // Node visitors.
53 #define DEF_VISIT(type) virtual void Visit##type(type* node) override; 56 #define DEF_VISIT(type) virtual void Visit##type(type* node) override;
54 AST_NODE_LIST(DEF_VISIT) 57 AST_NODE_LIST(DEF_VISIT)
55 #undef DEF_VISIT 58 #undef DEF_VISIT
56 59
57 void VisitIterationStatement(IterationStatement* stmt); 60 void VisitIterationStatement(IterationStatement* stmt);
58 61
59 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 62 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
60 }; 63 };
61 64
62 65
66 Statement* Processor::AssignUndefinedBefore(Statement* s) {
67 Expression* result_proxy = factory()->NewVariableProxy(result_);
68 Expression* undef = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
69 Expression* assignment = factory()->NewAssignment(
70 Token::ASSIGN, result_proxy, undef, RelocInfo::kNoPosition);
71 Block* b = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
72 b->AddStatement(
73 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
74 zone());
75 b->AddStatement(s, zone());
76 return b;
77 }
78
79
63 void Processor::Process(ZoneList<Statement*>* statements) { 80 void Processor::Process(ZoneList<Statement*>* statements) {
64 for (int i = statements->length() - 1; i >= 0; --i) { 81 for (int i = statements->length() - 1; i >= 0; --i) {
65 Visit(statements->at(i)); 82 Visit(statements->at(i));
66 statements->Set(i, replacement_); 83 statements->Set(i, replacement_);
67 } 84 }
68 } 85 }
69 86
70 87
71 void Processor::VisitBlock(Block* node) { 88 void Processor::VisitBlock(Block* node) {
72 // An initializer block is the rewritten form of a variable declaration 89 // An initializer block is the rewritten form of a variable declaration
(...skipping 23 matching lines...) Expand all
96 // Rewrite both branches. 113 // Rewrite both branches.
97 bool set_after = is_set_; 114 bool set_after = is_set_;
98 Visit(node->then_statement()); 115 Visit(node->then_statement());
99 node->set_then_statement(replacement_); 116 node->set_then_statement(replacement_);
100 bool set_in_then = is_set_; 117 bool set_in_then = is_set_;
101 is_set_ = set_after; 118 is_set_ = set_after;
102 Visit(node->else_statement()); 119 Visit(node->else_statement());
103 node->set_else_statement(replacement_); 120 node->set_else_statement(replacement_);
104 is_set_ = is_set_ && set_in_then; 121 is_set_ = is_set_ && set_in_then;
105 replacement_ = node; 122 replacement_ = node;
123
124 if (FLAG_harmony_completion && !is_set_) {
125 is_set_ = true;
rossberg 2015/09/28 14:09:22 Why not move this into AssignUndefinedBeforeNode?
neis 2015/10/05 10:57:28 I prefer the is_set_ logic to be explicit in the V
126 replacement_ = AssignUndefinedBefore(node);
127 }
106 } 128 }
107 129
108 130
109 void Processor::VisitIterationStatement(IterationStatement* node) { 131 void Processor::VisitIterationStatement(IterationStatement* node) {
110 // Rewrite the body. 132 // Rewrite the body.
111 bool set_after = is_set_; 133 bool set_after = is_set_;
112 is_set_ = false; // We are in a loop, so we can't rely on [set_after]. 134 is_set_ = false; // We are in a loop, so we can't rely on [set_after].
113 Visit(node->body()); 135 Visit(node->body());
114 node->set_body(replacement_); 136 node->set_body(replacement_);
115 is_set_ = is_set_ && set_after; 137 is_set_ = is_set_ && set_after;
116 replacement_ = node; 138 replacement_ = node;
139
140 if (FLAG_harmony_completion && !is_set_) {
141 is_set_ = true;
142 replacement_ = AssignUndefinedBefore(node);
143 }
117 } 144 }
118 145
119 146
120 void Processor::VisitDoWhileStatement(DoWhileStatement* node) { 147 void Processor::VisitDoWhileStatement(DoWhileStatement* node) {
121 VisitIterationStatement(node); 148 VisitIterationStatement(node);
122 } 149 }
123 150
124 151
125 void Processor::VisitWhileStatement(WhileStatement* node) { 152 void Processor::VisitWhileStatement(WhileStatement* node) {
126 VisitIterationStatement(node); 153 VisitIterationStatement(node);
(...skipping 19 matching lines...) Expand all
146 // Rewrite both try and catch block. 173 // Rewrite both try and catch block.
147 bool set_after = is_set_; 174 bool set_after = is_set_;
148 Visit(node->try_block()); 175 Visit(node->try_block());
149 node->set_try_block(static_cast<Block*>(replacement_)); 176 node->set_try_block(static_cast<Block*>(replacement_));
150 bool set_in_try = is_set_; 177 bool set_in_try = is_set_;
151 is_set_ = set_after; 178 is_set_ = set_after;
152 Visit(node->catch_block()); 179 Visit(node->catch_block());
153 node->set_catch_block(static_cast<Block*>(replacement_)); 180 node->set_catch_block(static_cast<Block*>(replacement_));
154 is_set_ = is_set_ && set_in_try; 181 is_set_ = is_set_ && set_in_try;
155 replacement_ = node; 182 replacement_ = node;
183
184 if (FLAG_harmony_completion && !is_set_) {
185 is_set_ = true;
186 replacement_ = AssignUndefinedBefore(node);
187 }
156 } 188 }
157 189
158 190
159 void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) { 191 void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) {
160 // Rewrite both try and finally block (in reverse order). 192 // Rewrite both try and finally block (in reverse order).
161 Visit(node->finally_block()); 193 Visit(node->finally_block());
162 node->set_finally_block(static_cast<Block*>(replacement_)); 194 node->set_finally_block(static_cast<Block*>(replacement_));
163 Visit(node->try_block()); // Exception will not be caught. 195 Visit(node->try_block()); // Exception will not be caught.
164 node->set_try_block(static_cast<Block*>(replacement_)); 196 node->set_try_block(static_cast<Block*>(replacement_));
165 replacement_ = node; 197 replacement_ = node;
198
199 if (FLAG_harmony_completion && !is_set_) {
200 is_set_ = true;
201 replacement_ = AssignUndefinedBefore(node);
202 }
166 } 203 }
167 204
168 205
169 void Processor::VisitSwitchStatement(SwitchStatement* node) { 206 void Processor::VisitSwitchStatement(SwitchStatement* node) {
170 // Rewrite statements in all case clauses (in reverse order). 207 // Rewrite statements in all case clauses (in reverse order).
171 ZoneList<CaseClause*>* clauses = node->cases(); 208 ZoneList<CaseClause*>* clauses = node->cases();
172 bool set_after = is_set_; 209 bool set_after = is_set_;
173 for (int i = clauses->length() - 1; i >= 0; --i) { 210 for (int i = clauses->length() - 1; i >= 0; --i) {
174 CaseClause* clause = clauses->at(i); 211 CaseClause* clause = clauses->at(i);
175 Process(clause->statements()); 212 Process(clause->statements());
176 } 213 }
177 is_set_ = is_set_ && set_after; 214 is_set_ = is_set_ && set_after;
178 replacement_ = node; 215 replacement_ = node;
216
217 if (FLAG_harmony_completion && !is_set_) {
218 is_set_ = true;
219 replacement_ = AssignUndefinedBefore(node);
220 }
179 } 221 }
180 222
181 223
182 void Processor::VisitContinueStatement(ContinueStatement* node) { 224 void Processor::VisitContinueStatement(ContinueStatement* node) {
183 is_set_ = false; 225 is_set_ = false;
184 replacement_ = node; 226 replacement_ = node;
185 } 227 }
186 228
187 229
188 void Processor::VisitBreakStatement(BreakStatement* node) { 230 void Processor::VisitBreakStatement(BreakStatement* node) {
189 is_set_ = false; 231 is_set_ = false;
190 replacement_ = node; 232 replacement_ = node;
191 } 233 }
192 234
193 235
194 void Processor::VisitWithStatement(WithStatement* node) { 236 void Processor::VisitWithStatement(WithStatement* node) {
195 Visit(node->statement()); 237 Visit(node->statement());
196 node->set_statement(replacement_); 238 node->set_statement(replacement_);
197 replacement_ = node; 239 replacement_ = node;
240
241 if (FLAG_harmony_completion && !is_set_) {
242 is_set_ = true;
243 replacement_ = AssignUndefinedBefore(node);
244 }
198 } 245 }
199 246
200 247
201 void Processor::VisitSloppyBlockFunctionStatement( 248 void Processor::VisitSloppyBlockFunctionStatement(
202 SloppyBlockFunctionStatement* node) { 249 SloppyBlockFunctionStatement* node) {
203 Visit(node->statement()); 250 Visit(node->statement());
204 node->set_statement(replacement_); 251 node->set_statement(replacement_);
205 replacement_ = node; 252 replacement_ = node;
206 } 253 }
207 254
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 processor.factory()->NewReturnStatement(result_proxy, pos); 316 processor.factory()->NewReturnStatement(result_proxy, pos);
270 body->Add(result_statement, info->zone()); 317 body->Add(result_statement, info->zone());
271 } 318 }
272 319
273 return true; 320 return true;
274 } 321 }
275 322
276 323
277 } // namespace internal 324 } // namespace internal
278 } // namespace v8 325 } // namespace v8
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | test/mjsunit/harmony/completion.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698