OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 117 |
118 private: | 118 private: |
119 void PrintIndent() { | 119 void PrintIndent() { |
120 for (intptr_t i = 0; i < *indent_; i++) { | 120 for (intptr_t i = 0; i < *indent_; i++) { |
121 OS::Print(". "); | 121 OS::Print(". "); |
122 } | 122 } |
123 } | 123 } |
124 intptr_t* indent_; | 124 intptr_t* indent_; |
125 }; | 125 }; |
126 | 126 |
127 | |
128 #define TRACE_PARSER(s) \ | 127 #define TRACE_PARSER(s) \ |
129 TraceParser __p__(this->TokenPos(), this->script_, &this->trace_indent_, s) | 128 TraceParser __p__(this->TokenPos(), this->script_, &this->trace_indent_, s) |
130 | 129 |
131 #else // not DEBUG | 130 #else // not DEBUG |
132 #define TRACE_PARSER(s) | 131 #define TRACE_PARSER(s) |
133 #endif // DEBUG | 132 #endif // DEBUG |
134 | 133 |
135 | |
136 class BoolScope : public ValueObject { | 134 class BoolScope : public ValueObject { |
137 public: | 135 public: |
138 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) { | 136 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) { |
139 *_addr = new_value; | 137 *_addr = new_value; |
140 } | 138 } |
141 ~BoolScope() { *_addr = _saved_value; } | 139 ~BoolScope() { *_addr = _saved_value; } |
142 | 140 |
143 private: | 141 private: |
144 bool* _addr; | 142 bool* _addr; |
145 bool _saved_value; | 143 bool _saved_value; |
146 }; | 144 }; |
147 | 145 |
148 | |
149 // Helper class to save and restore token position. | 146 // Helper class to save and restore token position. |
150 class Parser::TokenPosScope : public ValueObject { | 147 class Parser::TokenPosScope : public ValueObject { |
151 public: | 148 public: |
152 explicit TokenPosScope(Parser* p) : p_(p) { saved_pos_ = p_->TokenPos(); } | 149 explicit TokenPosScope(Parser* p) : p_(p) { saved_pos_ = p_->TokenPos(); } |
153 TokenPosScope(Parser* p, TokenPosition pos) : p_(p), saved_pos_(pos) {} | 150 TokenPosScope(Parser* p, TokenPosition pos) : p_(p), saved_pos_(pos) {} |
154 ~TokenPosScope() { p_->SetPosition(saved_pos_); } | 151 ~TokenPosScope() { p_->SetPosition(saved_pos_); } |
155 | 152 |
156 private: | 153 private: |
157 Parser* p_; | 154 Parser* p_; |
158 TokenPosition saved_pos_; | 155 TokenPosition saved_pos_; |
159 DISALLOW_COPY_AND_ASSIGN(TokenPosScope); | 156 DISALLOW_COPY_AND_ASSIGN(TokenPosScope); |
160 }; | 157 }; |
161 | 158 |
162 | |
163 class RecursionChecker : public ValueObject { | 159 class RecursionChecker : public ValueObject { |
164 public: | 160 public: |
165 explicit RecursionChecker(Parser* p) : parser_(p) { | 161 explicit RecursionChecker(Parser* p) : parser_(p) { |
166 parser_->recursion_counter_++; | 162 parser_->recursion_counter_++; |
167 // No need to check the stack unless the parser is in an unusually deep | 163 // No need to check the stack unless the parser is in an unusually deep |
168 // recurive state. Thus, we omit the more expensive stack checks in | 164 // recurive state. Thus, we omit the more expensive stack checks in |
169 // the common case. | 165 // the common case. |
170 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. | 166 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. |
171 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { | 167 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { |
172 parser_->CheckStack(); | 168 parser_->CheckStack(); |
173 } | 169 } |
174 } | 170 } |
175 ~RecursionChecker() { parser_->recursion_counter_--; } | 171 ~RecursionChecker() { parser_->recursion_counter_--; } |
176 | 172 |
177 private: | 173 private: |
178 Parser* parser_; | 174 Parser* parser_; |
179 }; | 175 }; |
180 | 176 |
181 | |
182 static RawTypeArguments* NewTypeArguments( | 177 static RawTypeArguments* NewTypeArguments( |
183 const GrowableArray<AbstractType*>& objs) { | 178 const GrowableArray<AbstractType*>& objs) { |
184 const TypeArguments& a = | 179 const TypeArguments& a = |
185 TypeArguments::Handle(TypeArguments::New(objs.length())); | 180 TypeArguments::Handle(TypeArguments::New(objs.length())); |
186 for (int i = 0; i < objs.length(); i++) { | 181 for (int i = 0; i < objs.length(); i++) { |
187 a.SetTypeAt(i, *objs.At(i)); | 182 a.SetTypeAt(i, *objs.At(i)); |
188 } | 183 } |
189 // Cannot canonicalize TypeArgument yet as its types may not have been | 184 // Cannot canonicalize TypeArgument yet as its types may not have been |
190 // finalized yet. | 185 // finalized yet. |
191 return a.raw(); | 186 return a.raw(); |
192 } | 187 } |
193 | 188 |
194 | |
195 void ParsedFunction::AddToGuardedFields(const Field* field) const { | 189 void ParsedFunction::AddToGuardedFields(const Field* field) const { |
196 if ((field->guarded_cid() == kDynamicCid) || | 190 if ((field->guarded_cid() == kDynamicCid) || |
197 (field->guarded_cid() == kIllegalCid)) { | 191 (field->guarded_cid() == kIllegalCid)) { |
198 return; | 192 return; |
199 } | 193 } |
200 | 194 |
201 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { | 195 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { |
202 const Field* other = (*guarded_fields_)[j]; | 196 const Field* other = (*guarded_fields_)[j]; |
203 if (field->Original() == other->Original()) { | 197 if (field->Original() == other->Original()) { |
204 // Abort background compilation early if the guarded state of this field | 198 // Abort background compilation early if the guarded state of this field |
(...skipping 11 matching lines...) Expand all Loading... |
216 } | 210 } |
217 | 211 |
218 // Note: the list of guarded fields must contain copies during background | 212 // Note: the list of guarded fields must contain copies during background |
219 // compilation because we will look at their guarded_cid when copying | 213 // compilation because we will look at their guarded_cid when copying |
220 // the array of guarded fields from callee into the caller during | 214 // the array of guarded fields from callee into the caller during |
221 // inlining. | 215 // inlining. |
222 ASSERT(!field->IsOriginal() || Thread::Current()->IsMutatorThread()); | 216 ASSERT(!field->IsOriginal() || Thread::Current()->IsMutatorThread()); |
223 guarded_fields_->Add(&Field::ZoneHandle(Z, field->raw())); | 217 guarded_fields_->Add(&Field::ZoneHandle(Z, field->raw())); |
224 } | 218 } |
225 | 219 |
226 | |
227 void ParsedFunction::Bailout(const char* origin, const char* reason) const { | 220 void ParsedFunction::Bailout(const char* origin, const char* reason) const { |
228 Report::MessageF(Report::kBailout, Script::Handle(function_.script()), | 221 Report::MessageF(Report::kBailout, Script::Handle(function_.script()), |
229 function_.token_pos(), Report::AtLocation, | 222 function_.token_pos(), Report::AtLocation, |
230 "%s Bailout in %s: %s", origin, | 223 "%s Bailout in %s: %s", origin, |
231 String::Handle(function_.name()).ToCString(), reason); | 224 String::Handle(function_.name()).ToCString(), reason); |
232 UNREACHABLE(); | 225 UNREACHABLE(); |
233 } | 226 } |
234 | 227 |
235 | |
236 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { | 228 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { |
237 if (kernel_scopes_ == NULL) { | 229 if (kernel_scopes_ == NULL) { |
238 intptr_t kernel_offset = function().kernel_offset(); | 230 intptr_t kernel_offset = function().kernel_offset(); |
239 Script& script = Script::Handle(Z, function().script()); | 231 Script& script = Script::Handle(Z, function().script()); |
240 kernel::StreamingScopeBuilder builder( | 232 kernel::StreamingScopeBuilder builder( |
241 this, kernel_offset, script.kernel_data(), script.kernel_data_size()); | 233 this, kernel_offset, script.kernel_data(), script.kernel_data_size()); |
242 kernel_scopes_ = builder.BuildScopes(); | 234 kernel_scopes_ = builder.BuildScopes(); |
243 } | 235 } |
244 return kernel_scopes_; | 236 return kernel_scopes_; |
245 } | 237 } |
246 | 238 |
247 | |
248 LocalVariable* ParsedFunction::EnsureExpressionTemp() { | 239 LocalVariable* ParsedFunction::EnsureExpressionTemp() { |
249 if (!has_expression_temp_var()) { | 240 if (!has_expression_temp_var()) { |
250 LocalVariable* temp = | 241 LocalVariable* temp = |
251 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), | 242 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), |
252 Symbols::ExprTemp(), Object::dynamic_type()); | 243 Symbols::ExprTemp(), Object::dynamic_type()); |
253 ASSERT(temp != NULL); | 244 ASSERT(temp != NULL); |
254 set_expression_temp_var(temp); | 245 set_expression_temp_var(temp); |
255 } | 246 } |
256 ASSERT(has_expression_temp_var()); | 247 ASSERT(has_expression_temp_var()); |
257 return expression_temp_var(); | 248 return expression_temp_var(); |
258 } | 249 } |
259 | 250 |
260 | |
261 void ParsedFunction::EnsureFinallyReturnTemp(bool is_async) { | 251 void ParsedFunction::EnsureFinallyReturnTemp(bool is_async) { |
262 if (!has_finally_return_temp_var()) { | 252 if (!has_finally_return_temp_var()) { |
263 LocalVariable* temp = | 253 LocalVariable* temp = |
264 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), | 254 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), |
265 Symbols::FinallyRetVal(), Object::dynamic_type()); | 255 Symbols::FinallyRetVal(), Object::dynamic_type()); |
266 ASSERT(temp != NULL); | 256 ASSERT(temp != NULL); |
267 temp->set_is_final(); | 257 temp->set_is_final(); |
268 if (is_async) { | 258 if (is_async) { |
269 temp->set_is_captured(); | 259 temp->set_is_captured(); |
270 } | 260 } |
271 set_finally_return_temp_var(temp); | 261 set_finally_return_temp_var(temp); |
272 } | 262 } |
273 ASSERT(has_finally_return_temp_var()); | 263 ASSERT(has_finally_return_temp_var()); |
274 } | 264 } |
275 | 265 |
276 | |
277 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 266 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
278 ASSERT(node_sequence_ == NULL); | 267 ASSERT(node_sequence_ == NULL); |
279 ASSERT(node_sequence != NULL); | 268 ASSERT(node_sequence != NULL); |
280 node_sequence_ = node_sequence; | 269 node_sequence_ = node_sequence; |
281 } | 270 } |
282 | 271 |
283 | |
284 void ParsedFunction::SetRegExpCompileData( | 272 void ParsedFunction::SetRegExpCompileData( |
285 RegExpCompileData* regexp_compile_data) { | 273 RegExpCompileData* regexp_compile_data) { |
286 ASSERT(regexp_compile_data_ == NULL); | 274 ASSERT(regexp_compile_data_ == NULL); |
287 ASSERT(regexp_compile_data != NULL); | 275 ASSERT(regexp_compile_data != NULL); |
288 regexp_compile_data_ = regexp_compile_data; | 276 regexp_compile_data_ = regexp_compile_data; |
289 } | 277 } |
290 | 278 |
291 | |
292 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { | 279 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { |
293 // 'deferred_prefixes_' are used to invalidate code, but no invalidation is | 280 // 'deferred_prefixes_' are used to invalidate code, but no invalidation is |
294 // needed if --load_deferred_eagerly. | 281 // needed if --load_deferred_eagerly. |
295 ASSERT(!FLAG_load_deferred_eagerly); | 282 ASSERT(!FLAG_load_deferred_eagerly); |
296 ASSERT(prefix.is_deferred_load()); | 283 ASSERT(prefix.is_deferred_load()); |
297 ASSERT(!prefix.is_loaded()); | 284 ASSERT(!prefix.is_loaded()); |
298 for (intptr_t i = 0; i < deferred_prefixes_->length(); i++) { | 285 for (intptr_t i = 0; i < deferred_prefixes_->length(); i++) { |
299 if ((*deferred_prefixes_)[i]->raw() == prefix.raw()) { | 286 if ((*deferred_prefixes_)[i]->raw() == prefix.raw()) { |
300 return; | 287 return; |
301 } | 288 } |
302 } | 289 } |
303 deferred_prefixes_->Add(&LibraryPrefix::ZoneHandle(Z, prefix.raw())); | 290 deferred_prefixes_->Add(&LibraryPrefix::ZoneHandle(Z, prefix.raw())); |
304 } | 291 } |
305 | 292 |
306 | |
307 void ParsedFunction::AllocateVariables() { | 293 void ParsedFunction::AllocateVariables() { |
308 ASSERT(!function().IsIrregexpFunction()); | 294 ASSERT(!function().IsIrregexpFunction()); |
309 LocalScope* scope = node_sequence()->scope(); | 295 LocalScope* scope = node_sequence()->scope(); |
310 const intptr_t num_fixed_params = function().num_fixed_parameters(); | 296 const intptr_t num_fixed_params = function().num_fixed_parameters(); |
311 const intptr_t num_opt_params = function().NumOptionalParameters(); | 297 const intptr_t num_opt_params = function().NumOptionalParameters(); |
312 const intptr_t num_params = num_fixed_params + num_opt_params; | 298 const intptr_t num_params = num_fixed_params + num_opt_params; |
313 // Compute start indices to parameters and locals, and the number of | 299 // Compute start indices to parameters and locals, and the number of |
314 // parameters to copy. | 300 // parameters to copy. |
315 if (num_opt_params == 0) { | 301 if (num_opt_params == 0) { |
316 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and | 302 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and |
(...skipping 14 matching lines...) Expand all Loading... |
331 bool found_captured_variables = false; | 317 bool found_captured_variables = false; |
332 int next_free_frame_index = scope->AllocateVariables( | 318 int next_free_frame_index = scope->AllocateVariables( |
333 first_parameter_index_, num_params, first_stack_local_index_, NULL, | 319 first_parameter_index_, num_params, first_stack_local_index_, NULL, |
334 &found_captured_variables); | 320 &found_captured_variables); |
335 | 321 |
336 // Frame indices are relative to the frame pointer and are decreasing. | 322 // Frame indices are relative to the frame pointer and are decreasing. |
337 ASSERT(next_free_frame_index <= first_stack_local_index_); | 323 ASSERT(next_free_frame_index <= first_stack_local_index_); |
338 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 324 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
339 } | 325 } |
340 | 326 |
341 | |
342 struct CatchParamDesc { | 327 struct CatchParamDesc { |
343 CatchParamDesc() | 328 CatchParamDesc() |
344 : token_pos(TokenPosition::kNoSource), | 329 : token_pos(TokenPosition::kNoSource), |
345 type(NULL), | 330 type(NULL), |
346 name(NULL), | 331 name(NULL), |
347 var(NULL) {} | 332 var(NULL) {} |
348 TokenPosition token_pos; | 333 TokenPosition token_pos; |
349 const AbstractType* type; | 334 const AbstractType* type; |
350 const String* name; | 335 const String* name; |
351 LocalVariable* var; | 336 LocalVariable* var; |
352 }; | 337 }; |
353 | 338 |
354 | |
355 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 339 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
356 ASSERT(function().IsIrregexpFunction()); | 340 ASSERT(function().IsIrregexpFunction()); |
357 ASSERT(function().NumOptionalParameters() == 0); | 341 ASSERT(function().NumOptionalParameters() == 0); |
358 const intptr_t num_params = function().num_fixed_parameters(); | 342 const intptr_t num_params = function().num_fixed_parameters(); |
359 ASSERT(num_params == RegExpMacroAssembler::kParamCount); | 343 ASSERT(num_params == RegExpMacroAssembler::kParamCount); |
360 // Compute start indices to parameters and locals, and the number of | 344 // Compute start indices to parameters and locals, and the number of |
361 // parameters to copy. | 345 // parameters to copy. |
362 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and | 346 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and |
363 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. | 347 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. |
364 first_parameter_index_ = kParamEndSlotFromFp + num_params; | 348 first_parameter_index_ = kParamEndSlotFromFp + num_params; |
365 first_stack_local_index_ = kFirstLocalSlotFromFp; | 349 first_stack_local_index_ = kFirstLocalSlotFromFp; |
366 num_copied_params_ = 0; | 350 num_copied_params_ = 0; |
367 | 351 |
368 // Frame indices are relative to the frame pointer and are decreasing. | 352 // Frame indices are relative to the frame pointer and are decreasing. |
369 num_stack_locals_ = num_stack_locals; | 353 num_stack_locals_ = num_stack_locals; |
370 } | 354 } |
371 | 355 |
372 | |
373 struct Parser::Block : public ZoneAllocated { | 356 struct Parser::Block : public ZoneAllocated { |
374 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) | 357 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) |
375 : parent(outer_block), scope(local_scope), statements(seq) { | 358 : parent(outer_block), scope(local_scope), statements(seq) { |
376 ASSERT(scope != NULL); | 359 ASSERT(scope != NULL); |
377 ASSERT(statements != NULL); | 360 ASSERT(statements != NULL); |
378 } | 361 } |
379 Block* parent; // Enclosing block, or NULL if outermost. | 362 Block* parent; // Enclosing block, or NULL if outermost. |
380 LocalScope* scope; | 363 LocalScope* scope; |
381 SequenceNode* statements; | 364 SequenceNode* statements; |
382 }; | 365 }; |
383 | 366 |
384 | |
385 // Class which describes an inlined finally block which is used to generate | 367 // Class which describes an inlined finally block which is used to generate |
386 // inlined code for the finally blocks when there is an exit from a try | 368 // inlined code for the finally blocks when there is an exit from a try |
387 // block using 'return', 'break' or 'continue'. | 369 // block using 'return', 'break' or 'continue'. |
388 class Parser::TryStack : public ZoneAllocated { | 370 class Parser::TryStack : public ZoneAllocated { |
389 public: | 371 public: |
390 TryStack(Block* try_block, TryStack* outer_try, intptr_t try_index) | 372 TryStack(Block* try_block, TryStack* outer_try, intptr_t try_index) |
391 : try_block_(try_block), | 373 : try_block_(try_block), |
392 inlined_finally_nodes_(), | 374 inlined_finally_nodes_(), |
393 outer_try_(outer_try), | 375 outer_try_(outer_try), |
394 try_index_(try_index), | 376 try_index_(try_index), |
(...skipping 23 matching lines...) Expand all Loading... |
418 GrowableArray<AstNode*> inlined_finally_nodes_; | 400 GrowableArray<AstNode*> inlined_finally_nodes_; |
419 TryStack* outer_try_; | 401 TryStack* outer_try_; |
420 const intptr_t try_index_; | 402 const intptr_t try_index_; |
421 bool inside_catch_; // True when parsing a catch clause of this try. | 403 bool inside_catch_; // True when parsing a catch clause of this try. |
422 bool inside_finally_; // True when parsing a finally clause of an inner try | 404 bool inside_finally_; // True when parsing a finally clause of an inner try |
423 // of this try. | 405 // of this try. |
424 | 406 |
425 DISALLOW_COPY_AND_ASSIGN(TryStack); | 407 DISALLOW_COPY_AND_ASSIGN(TryStack); |
426 }; | 408 }; |
427 | 409 |
428 | |
429 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { | 410 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { |
430 inlined_finally_nodes_.Add(node); | 411 inlined_finally_nodes_.Add(node); |
431 } | 412 } |
432 | 413 |
433 | |
434 void Parser::TryStack::RemoveJumpToLabel(SourceLabel* label) { | 414 void Parser::TryStack::RemoveJumpToLabel(SourceLabel* label) { |
435 int i = 0; | 415 int i = 0; |
436 while (i < inlined_finally_nodes_.length()) { | 416 while (i < inlined_finally_nodes_.length()) { |
437 if (inlined_finally_nodes_[i]->IsJumpNode()) { | 417 if (inlined_finally_nodes_[i]->IsJumpNode()) { |
438 JumpNode* jump = inlined_finally_nodes_[i]->AsJumpNode(); | 418 JumpNode* jump = inlined_finally_nodes_[i]->AsJumpNode(); |
439 if (jump->label() == label) { | 419 if (jump->label() == label) { |
440 // Shift remaining entries left and delete last entry. | 420 // Shift remaining entries left and delete last entry. |
441 for (int j = i + 1; j < inlined_finally_nodes_.length(); j++) { | 421 for (int j = i + 1; j < inlined_finally_nodes_.length(); j++) { |
442 inlined_finally_nodes_[j - 1] = inlined_finally_nodes_[j]; | 422 inlined_finally_nodes_[j - 1] = inlined_finally_nodes_[j]; |
443 } | 423 } |
444 inlined_finally_nodes_.RemoveLast(); | 424 inlined_finally_nodes_.RemoveLast(); |
445 continue; | 425 continue; |
446 } | 426 } |
447 } | 427 } |
448 i++; | 428 i++; |
449 } | 429 } |
450 } | 430 } |
451 | 431 |
452 | |
453 // For parsing a compilation unit. | 432 // For parsing a compilation unit. |
454 Parser::Parser(const Script& script, | 433 Parser::Parser(const Script& script, |
455 const Library& library, | 434 const Library& library, |
456 TokenPosition token_pos) | 435 TokenPosition token_pos) |
457 : thread_(Thread::Current()), | 436 : thread_(Thread::Current()), |
458 isolate_(thread()->isolate()), | 437 isolate_(thread()->isolate()), |
459 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), | 438 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), |
460 script_(Script::Handle(zone(), script.raw())), | 439 script_(Script::Handle(zone(), script.raw())), |
461 tokens_iterator_(zone(), | 440 tokens_iterator_(zone(), |
462 TokenStream::Handle(zone(), script.tokens()), | 441 TokenStream::Handle(zone(), script.tokens()), |
(...skipping 12 matching lines...) Expand all Loading... |
475 try_stack_(NULL), | 454 try_stack_(NULL), |
476 last_used_try_index_(0), | 455 last_used_try_index_(0), |
477 unregister_pending_function_(false), | 456 unregister_pending_function_(false), |
478 async_temp_scope_(NULL), | 457 async_temp_scope_(NULL), |
479 trace_indent_(0), | 458 trace_indent_(0), |
480 recursion_counter_(0) { | 459 recursion_counter_(0) { |
481 ASSERT(tokens_iterator_.IsValid()); | 460 ASSERT(tokens_iterator_.IsValid()); |
482 ASSERT(!library.IsNull()); | 461 ASSERT(!library.IsNull()); |
483 } | 462 } |
484 | 463 |
485 | |
486 // For parsing a function. | 464 // For parsing a function. |
487 Parser::Parser(const Script& script, | 465 Parser::Parser(const Script& script, |
488 ParsedFunction* parsed_function, | 466 ParsedFunction* parsed_function, |
489 TokenPosition token_pos) | 467 TokenPosition token_pos) |
490 : thread_(Thread::Current()), | 468 : thread_(Thread::Current()), |
491 isolate_(thread()->isolate()), | 469 isolate_(thread()->isolate()), |
492 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), | 470 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), |
493 script_(Script::Handle(zone(), script.raw())), | 471 script_(Script::Handle(zone(), script.raw())), |
494 tokens_iterator_(zone(), | 472 tokens_iterator_(zone(), |
495 TokenStream::Handle(zone(), script.tokens()), | 473 TokenStream::Handle(zone(), script.tokens()), |
(...skipping 18 matching lines...) Expand all Loading... |
514 last_used_try_index_(0), | 492 last_used_try_index_(0), |
515 unregister_pending_function_(false), | 493 unregister_pending_function_(false), |
516 async_temp_scope_(NULL), | 494 async_temp_scope_(NULL), |
517 trace_indent_(0), | 495 trace_indent_(0), |
518 recursion_counter_(0) { | 496 recursion_counter_(0) { |
519 ASSERT(tokens_iterator_.IsValid()); | 497 ASSERT(tokens_iterator_.IsValid()); |
520 ASSERT(!current_function().IsNull()); | 498 ASSERT(!current_function().IsNull()); |
521 EnsureExpressionTemp(); | 499 EnsureExpressionTemp(); |
522 } | 500 } |
523 | 501 |
524 | |
525 Parser::~Parser() { | 502 Parser::~Parser() { |
526 if (unregister_pending_function_) { | 503 if (unregister_pending_function_) { |
527 const GrowableObjectArray& pending_functions = | 504 const GrowableObjectArray& pending_functions = |
528 GrowableObjectArray::Handle(T->pending_functions()); | 505 GrowableObjectArray::Handle(T->pending_functions()); |
529 ASSERT(!pending_functions.IsNull()); | 506 ASSERT(!pending_functions.IsNull()); |
530 ASSERT(pending_functions.Length() > 0); | 507 ASSERT(pending_functions.Length() > 0); |
531 ASSERT(pending_functions.At(pending_functions.Length() - 1) == | 508 ASSERT(pending_functions.At(pending_functions.Length() - 1) == |
532 current_function().raw()); | 509 current_function().raw()); |
533 pending_functions.RemoveLast(); | 510 pending_functions.RemoveLast(); |
534 } | 511 } |
535 } | 512 } |
536 | 513 |
537 | |
538 // Each try in this function gets its own try index. | 514 // Each try in this function gets its own try index. |
539 // See definition of RawPcDescriptors::PcDescriptor. | 515 // See definition of RawPcDescriptors::PcDescriptor. |
540 int16_t Parser::AllocateTryIndex() { | 516 int16_t Parser::AllocateTryIndex() { |
541 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { | 517 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { |
542 ReportError("too many nested try statements"); | 518 ReportError("too many nested try statements"); |
543 } | 519 } |
544 return last_used_try_index_++; | 520 return last_used_try_index_++; |
545 } | 521 } |
546 | 522 |
547 | |
548 void Parser::SetScript(const Script& script, TokenPosition token_pos) { | 523 void Parser::SetScript(const Script& script, TokenPosition token_pos) { |
549 script_ = script.raw(); | 524 script_ = script.raw(); |
550 tokens_iterator_.SetStream(TokenStream::Handle(Z, script.tokens()), | 525 tokens_iterator_.SetStream(TokenStream::Handle(Z, script.tokens()), |
551 token_pos); | 526 token_pos); |
552 token_kind_ = Token::kILLEGAL; | 527 token_kind_ = Token::kILLEGAL; |
553 } | 528 } |
554 | 529 |
555 | |
556 bool Parser::SetAllowFunctionLiterals(bool value) { | 530 bool Parser::SetAllowFunctionLiterals(bool value) { |
557 bool current_value = allow_function_literals_; | 531 bool current_value = allow_function_literals_; |
558 allow_function_literals_ = value; | 532 allow_function_literals_ = value; |
559 return current_value; | 533 return current_value; |
560 } | 534 } |
561 | 535 |
562 | |
563 const Function& Parser::current_function() const { | 536 const Function& Parser::current_function() const { |
564 ASSERT(parsed_function() != NULL); | 537 ASSERT(parsed_function() != NULL); |
565 return parsed_function()->function(); | 538 return parsed_function()->function(); |
566 } | 539 } |
567 | 540 |
568 | |
569 const Function& Parser::innermost_function() const { | 541 const Function& Parser::innermost_function() const { |
570 return innermost_function_; | 542 return innermost_function_; |
571 } | 543 } |
572 | 544 |
573 | |
574 int Parser::FunctionLevel() const { | 545 int Parser::FunctionLevel() const { |
575 if (current_block_ != NULL) { | 546 if (current_block_ != NULL) { |
576 return current_block_->scope->function_level(); | 547 return current_block_->scope->function_level(); |
577 } | 548 } |
578 return 0; | 549 return 0; |
579 } | 550 } |
580 | 551 |
581 | |
582 const Class& Parser::current_class() const { | 552 const Class& Parser::current_class() const { |
583 return current_class_; | 553 return current_class_; |
584 } | 554 } |
585 | 555 |
586 | |
587 void Parser::set_current_class(const Class& value) { | 556 void Parser::set_current_class(const Class& value) { |
588 current_class_ = value.raw(); | 557 current_class_ = value.raw(); |
589 } | 558 } |
590 | 559 |
591 | |
592 void Parser::SetPosition(TokenPosition position) { | 560 void Parser::SetPosition(TokenPosition position) { |
593 tokens_iterator_.SetCurrentPosition(position); | 561 tokens_iterator_.SetCurrentPosition(position); |
594 token_kind_ = Token::kILLEGAL; | 562 token_kind_ = Token::kILLEGAL; |
595 prev_token_pos_ = position; | 563 prev_token_pos_ = position; |
596 } | 564 } |
597 | 565 |
598 | |
599 // Set state and increments generational count so that thge background compiler | 566 // Set state and increments generational count so that thge background compiler |
600 // can detect if loading/top-level-parsing occured during compilation. | 567 // can detect if loading/top-level-parsing occured during compilation. |
601 class TopLevelParsingScope : public StackResource { | 568 class TopLevelParsingScope : public StackResource { |
602 public: | 569 public: |
603 explicit TopLevelParsingScope(Thread* thread) : StackResource(thread) { | 570 explicit TopLevelParsingScope(Thread* thread) : StackResource(thread) { |
604 isolate()->IncrTopLevelParsingCount(); | 571 isolate()->IncrTopLevelParsingCount(); |
605 } | 572 } |
606 ~TopLevelParsingScope() { | 573 ~TopLevelParsingScope() { |
607 isolate()->DecrTopLevelParsingCount(); | 574 isolate()->DecrTopLevelParsingCount(); |
608 isolate()->IncrLoadingInvalidationGen(); | 575 isolate()->IncrLoadingInvalidationGen(); |
609 } | 576 } |
610 }; | 577 }; |
611 | 578 |
612 | |
613 void Parser::ParseCompilationUnit(const Library& library, | 579 void Parser::ParseCompilationUnit(const Library& library, |
614 const Script& script) { | 580 const Script& script) { |
615 Thread* thread = Thread::Current(); | 581 Thread* thread = Thread::Current(); |
616 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 582 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
617 CSTAT_TIMER_SCOPE(thread, parser_timer); | 583 CSTAT_TIMER_SCOPE(thread, parser_timer); |
618 #ifndef PRODUCT | 584 #ifndef PRODUCT |
619 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 585 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
620 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 586 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
621 "CompileTopLevel"); | 587 "CompileTopLevel"); |
622 if (tds.enabled()) { | 588 if (tds.enabled()) { |
623 tds.SetNumArguments(1); | 589 tds.SetNumArguments(1); |
624 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); | 590 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); |
625 } | 591 } |
626 #endif | 592 #endif |
627 | 593 |
628 TopLevelParsingScope scope(thread); | 594 TopLevelParsingScope scope(thread); |
629 Parser parser(script, library, TokenPosition::kMinSource); | 595 Parser parser(script, library, TokenPosition::kMinSource); |
630 parser.ParseTopLevel(); | 596 parser.ParseTopLevel(); |
631 } | 597 } |
632 | 598 |
633 | |
634 void Parser::ComputeCurrentToken() { | 599 void Parser::ComputeCurrentToken() { |
635 ASSERT(token_kind_ == Token::kILLEGAL); | 600 ASSERT(token_kind_ == Token::kILLEGAL); |
636 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 601 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
637 if (token_kind_ == Token::kERROR) { | 602 if (token_kind_ == Token::kERROR) { |
638 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 603 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
639 } | 604 } |
640 } | 605 } |
641 | 606 |
642 | |
643 Token::Kind Parser::LookaheadToken(int num_tokens) { | 607 Token::Kind Parser::LookaheadToken(int num_tokens) { |
644 return tokens_iterator_.LookaheadTokenKind(num_tokens); | 608 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
645 } | 609 } |
646 | 610 |
647 | |
648 String* Parser::CurrentLiteral() const { | 611 String* Parser::CurrentLiteral() const { |
649 String& result = String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); | 612 String& result = String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); |
650 return &result; | 613 return &result; |
651 } | 614 } |
652 | 615 |
653 | |
654 RawDouble* Parser::CurrentDoubleLiteral() const { | 616 RawDouble* Parser::CurrentDoubleLiteral() const { |
655 literal_token_ ^= tokens_iterator_.CurrentToken(); | 617 literal_token_ ^= tokens_iterator_.CurrentToken(); |
656 ASSERT(literal_token_.kind() == Token::kDOUBLE); | 618 ASSERT(literal_token_.kind() == Token::kDOUBLE); |
657 return Double::RawCast(literal_token_.value()); | 619 return Double::RawCast(literal_token_.value()); |
658 } | 620 } |
659 | 621 |
660 | |
661 RawInteger* Parser::CurrentIntegerLiteral() const { | 622 RawInteger* Parser::CurrentIntegerLiteral() const { |
662 literal_token_ ^= tokens_iterator_.CurrentToken(); | 623 literal_token_ ^= tokens_iterator_.CurrentToken(); |
663 ASSERT(literal_token_.kind() == Token::kINTEGER); | 624 ASSERT(literal_token_.kind() == Token::kINTEGER); |
664 RawInteger* ri = Integer::RawCast(literal_token_.value()); | 625 RawInteger* ri = Integer::RawCast(literal_token_.value()); |
665 return ri; | 626 return ri; |
666 } | 627 } |
667 | 628 |
668 | |
669 struct ParamDesc { | 629 struct ParamDesc { |
670 ParamDesc() | 630 ParamDesc() |
671 : type(NULL), | 631 : type(NULL), |
672 name_pos(TokenPosition::kNoSource), | 632 name_pos(TokenPosition::kNoSource), |
673 name(NULL), | 633 name(NULL), |
674 default_value(NULL), | 634 default_value(NULL), |
675 metadata(NULL), | 635 metadata(NULL), |
676 var(NULL), | 636 var(NULL), |
677 is_final(false), | 637 is_final(false), |
678 is_field_initializer(false), | 638 is_field_initializer(false), |
679 has_explicit_type(false), | 639 has_explicit_type(false), |
680 is_covariant(false) {} | 640 is_covariant(false) {} |
681 const AbstractType* type; | 641 const AbstractType* type; |
682 TokenPosition name_pos; | 642 TokenPosition name_pos; |
683 const String* name; | 643 const String* name; |
684 const Instance* default_value; // NULL if not an optional parameter. | 644 const Instance* default_value; // NULL if not an optional parameter. |
685 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 645 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
686 LocalVariable* var; // Scope variable allocated for this parameter. | 646 LocalVariable* var; // Scope variable allocated for this parameter. |
687 bool is_final; | 647 bool is_final; |
688 bool is_field_initializer; | 648 bool is_field_initializer; |
689 bool has_explicit_type; | 649 bool has_explicit_type; |
690 bool is_covariant; | 650 bool is_covariant; |
691 }; | 651 }; |
692 | 652 |
693 | |
694 struct ParamList { | 653 struct ParamList { |
695 ParamList() { Clear(); } | 654 ParamList() { Clear(); } |
696 | 655 |
697 void Clear() { | 656 void Clear() { |
698 num_fixed_parameters = 0; | 657 num_fixed_parameters = 0; |
699 num_optional_parameters = 0; | 658 num_optional_parameters = 0; |
700 has_optional_positional_parameters = false; | 659 has_optional_positional_parameters = false; |
701 has_optional_named_parameters = false; | 660 has_optional_named_parameters = false; |
702 has_explicit_default_values = false; | 661 has_explicit_default_values = false; |
703 has_field_initializer = false; | 662 has_field_initializer = false; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 bool has_optional_positional_parameters; | 721 bool has_optional_positional_parameters; |
763 bool has_optional_named_parameters; | 722 bool has_optional_named_parameters; |
764 bool has_explicit_default_values; | 723 bool has_explicit_default_values; |
765 bool has_field_initializer; | 724 bool has_field_initializer; |
766 bool has_covariant; | 725 bool has_covariant; |
767 bool implicitly_final; | 726 bool implicitly_final; |
768 bool skipped; | 727 bool skipped; |
769 ZoneGrowableArray<ParamDesc>* parameters; | 728 ZoneGrowableArray<ParamDesc>* parameters; |
770 }; | 729 }; |
771 | 730 |
772 | |
773 struct MemberDesc { | 731 struct MemberDesc { |
774 MemberDesc() { Clear(); } | 732 MemberDesc() { Clear(); } |
775 | 733 |
776 void Clear() { | 734 void Clear() { |
777 has_abstract = false; | 735 has_abstract = false; |
778 has_external = false; | 736 has_external = false; |
779 has_covariant = false; | 737 has_covariant = false; |
780 has_final = false; | 738 has_final = false; |
781 has_const = false; | 739 has_const = false; |
782 has_static = false; | 740 has_static = false; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 // For constructors: NULL for unnamed constructor, | 803 // For constructors: NULL for unnamed constructor, |
846 // identifier after classname for named constructors. | 804 // identifier after classname for named constructors. |
847 // For getters and setters: unmangled name. | 805 // For getters and setters: unmangled name. |
848 String* dict_name; | 806 String* dict_name; |
849 ParamList params; | 807 ParamList params; |
850 RawFunction::Kind kind; | 808 RawFunction::Kind kind; |
851 // NULL for functions, field object for static or instance fields. | 809 // NULL for functions, field object for static or instance fields. |
852 Field* field_; | 810 Field* field_; |
853 }; | 811 }; |
854 | 812 |
855 | |
856 class ClassDesc : public ValueObject { | 813 class ClassDesc : public ValueObject { |
857 public: | 814 public: |
858 ClassDesc(Zone* zone, | 815 ClassDesc(Zone* zone, |
859 const Class& cls, | 816 const Class& cls, |
860 const String& cls_name, | 817 const String& cls_name, |
861 bool is_interface, | 818 bool is_interface, |
862 TokenPosition token_pos) | 819 TokenPosition token_pos) |
863 : zone_(zone), | 820 : zone_(zone), |
864 clazz_(cls), | 821 clazz_(cls), |
865 class_name_(cls_name), | 822 class_name_(cls_name), |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 private: | 877 private: |
921 Zone* zone_; | 878 Zone* zone_; |
922 const Class& clazz_; | 879 const Class& clazz_; |
923 const String& class_name_; | 880 const String& class_name_; |
924 TokenPosition token_pos_; // Token index of "class" keyword. | 881 TokenPosition token_pos_; // Token index of "class" keyword. |
925 GrowableArray<const Function*> functions_; | 882 GrowableArray<const Function*> functions_; |
926 GrowableArray<const Field*> fields_; | 883 GrowableArray<const Field*> fields_; |
927 GrowableArray<MemberDesc> members_; | 884 GrowableArray<MemberDesc> members_; |
928 }; | 885 }; |
929 | 886 |
930 | |
931 class TopLevel : public ValueObject { | 887 class TopLevel : public ValueObject { |
932 public: | 888 public: |
933 explicit TopLevel(Zone* zone) | 889 explicit TopLevel(Zone* zone) |
934 : zone_(zone), fields_(zone, 4), functions_(zone, 4) {} | 890 : zone_(zone), fields_(zone, 4), functions_(zone, 4) {} |
935 | 891 |
936 void AddField(const Field& field) { | 892 void AddField(const Field& field) { |
937 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); | 893 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); |
938 } | 894 } |
939 | 895 |
940 void AddFunction(const Function& function) { | 896 void AddFunction(const Function& function) { |
941 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); | 897 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); |
942 } | 898 } |
943 | 899 |
944 const GrowableArray<const Field*>& fields() const { return fields_; } | 900 const GrowableArray<const Field*>& fields() const { return fields_; } |
945 | 901 |
946 const GrowableArray<const Function*>& functions() const { return functions_; } | 902 const GrowableArray<const Function*>& functions() const { return functions_; } |
947 | 903 |
948 private: | 904 private: |
949 Zone* zone_; | 905 Zone* zone_; |
950 GrowableArray<const Field*> fields_; | 906 GrowableArray<const Field*> fields_; |
951 GrowableArray<const Function*> functions_; | 907 GrowableArray<const Function*> functions_; |
952 }; | 908 }; |
953 | 909 |
954 | |
955 void Parser::ParseClass(const Class& cls) { | 910 void Parser::ParseClass(const Class& cls) { |
956 Thread* thread = Thread::Current(); | 911 Thread* thread = Thread::Current(); |
957 Zone* zone = thread->zone(); | 912 Zone* zone = thread->zone(); |
958 const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed); | 913 const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed); |
959 #ifndef PRODUCT | 914 #ifndef PRODUCT |
960 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 915 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
961 "ParseClass"); | 916 "ParseClass"); |
962 if (tds.enabled()) { | 917 if (tds.enabled()) { |
963 tds.SetNumArguments(1); | 918 tds.SetNumArguments(1); |
964 tds.CopyArgument(0, "class", String::Handle(cls.Name()).ToCString()); | 919 tds.CopyArgument(0, "class", String::Handle(cls.Name()).ToCString()); |
(...skipping 11 matching lines...) Expand all Loading... |
976 CSTAT_TIMER_SCOPE(thread, parser_timer); | 931 CSTAT_TIMER_SCOPE(thread, parser_timer); |
977 const Script& script = Script::Handle(zone, cls.script()); | 932 const Script& script = Script::Handle(zone, cls.script()); |
978 const Library& lib = Library::Handle(zone, cls.library()); | 933 const Library& lib = Library::Handle(zone, cls.library()); |
979 Parser parser(script, lib, cls.token_pos()); | 934 Parser parser(script, lib, cls.token_pos()); |
980 parser.ParseEnumDefinition(cls); | 935 parser.ParseEnumDefinition(cls); |
981 } | 936 } |
982 const int64_t num_tokes_after = STAT_VALUE(thread, num_tokens_consumed); | 937 const int64_t num_tokes_after = STAT_VALUE(thread, num_tokens_consumed); |
983 INC_STAT(thread, num_class_tokens, num_tokes_after - num_tokes_before); | 938 INC_STAT(thread, num_class_tokens, num_tokes_after - num_tokes_before); |
984 } | 939 } |
985 | 940 |
986 | |
987 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, | 941 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, |
988 TokenPosition* start, | 942 TokenPosition* start, |
989 TokenPosition* end) { | 943 TokenPosition* end) { |
990 if (!field.has_initializer()) { | 944 if (!field.has_initializer()) { |
991 return false; | 945 return false; |
992 } | 946 } |
993 Thread* thread = Thread::Current(); | 947 Thread* thread = Thread::Current(); |
994 Zone* zone = thread->zone(); | 948 Zone* zone = thread->zone(); |
995 const Class& cls = Class::Handle(zone, field.Owner()); | 949 const Class& cls = Class::Handle(zone, field.Owner()); |
996 const Script& script = Script::Handle(zone, cls.script()); | 950 const Script& script = Script::Handle(zone, cls.script()); |
(...skipping 16 matching lines...) Expand all Loading... |
1013 *start = TokenPos(); | 967 *start = TokenPos(); |
1014 if (IsFunctionLiteral()) { | 968 if (IsFunctionLiteral()) { |
1015 SkipExpr(); | 969 SkipExpr(); |
1016 *end = PrevTokenPos(); | 970 *end = PrevTokenPos(); |
1017 return true; | 971 return true; |
1018 } | 972 } |
1019 | 973 |
1020 return false; | 974 return false; |
1021 } | 975 } |
1022 | 976 |
1023 | |
1024 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 977 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
1025 ASSERT(!func.IsNull()); | 978 ASSERT(!func.IsNull()); |
1026 LongJumpScope jump; | 979 LongJumpScope jump; |
1027 if (setjmp(*jump.Set()) == 0) { | 980 if (setjmp(*jump.Set()) == 0) { |
1028 Thread* thread = Thread::Current(); | 981 Thread* thread = Thread::Current(); |
1029 StackZone stack_zone(thread); | 982 StackZone stack_zone(thread); |
1030 Zone* zone = stack_zone.GetZone(); | 983 Zone* zone = stack_zone.GetZone(); |
1031 const Script& script = Script::Handle(zone, func.script()); | 984 const Script& script = Script::Handle(zone, func.script()); |
1032 const Class& owner = Class::Handle(zone, func.Owner()); | 985 const Class& owner = Class::Handle(zone, func.Owner()); |
1033 ASSERT(!owner.IsNull()); | 986 ASSERT(!owner.IsNull()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 Thread* thread = Thread::Current(); | 1021 Thread* thread = Thread::Current(); |
1069 Error& error = Error::Handle(); | 1022 Error& error = Error::Handle(); |
1070 error = thread->sticky_error(); | 1023 error = thread->sticky_error(); |
1071 thread->clear_sticky_error(); | 1024 thread->clear_sticky_error(); |
1072 return error.raw(); | 1025 return error.raw(); |
1073 } | 1026 } |
1074 UNREACHABLE(); | 1027 UNREACHABLE(); |
1075 return Object::null(); | 1028 return Object::null(); |
1076 } | 1029 } |
1077 | 1030 |
1078 | |
1079 bool Parser::ParseFormalParameters(const Function& func, ParamList* params) { | 1031 bool Parser::ParseFormalParameters(const Function& func, ParamList* params) { |
1080 ASSERT(!func.IsNull()); | 1032 ASSERT(!func.IsNull()); |
1081 // This is currently only used for constructors. To handle all kinds | 1033 // This is currently only used for constructors. To handle all kinds |
1082 // of functions, special cases for getters and possibly other kinds | 1034 // of functions, special cases for getters and possibly other kinds |
1083 // need to be added. | 1035 // need to be added. |
1084 ASSERT(func.kind() == RawFunction::kConstructor); | 1036 ASSERT(func.kind() == RawFunction::kConstructor); |
1085 ASSERT(!func.IsRedirectingFactory()); | 1037 ASSERT(!func.IsRedirectingFactory()); |
1086 // Implicit constructors have no source, no user-defined formal parameters. | 1038 // Implicit constructors have no source, no user-defined formal parameters. |
1087 if (func.IsImplicitConstructor()) { | 1039 if (func.IsImplicitConstructor()) { |
1088 return true; | 1040 return true; |
(...skipping 16 matching lines...) Expand all Loading... |
1105 return true; | 1057 return true; |
1106 } else { | 1058 } else { |
1107 Thread::Current()->clear_sticky_error(); | 1059 Thread::Current()->clear_sticky_error(); |
1108 params->Clear(); | 1060 params->Clear(); |
1109 return false; | 1061 return false; |
1110 } | 1062 } |
1111 UNREACHABLE(); | 1063 UNREACHABLE(); |
1112 return false; | 1064 return false; |
1113 } | 1065 } |
1114 | 1066 |
1115 | |
1116 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 1067 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
1117 Thread* thread = parsed_function->thread(); | 1068 Thread* thread = parsed_function->thread(); |
1118 ASSERT(thread == Thread::Current()); | 1069 ASSERT(thread == Thread::Current()); |
1119 Zone* zone = thread->zone(); | 1070 Zone* zone = thread->zone(); |
1120 CSTAT_TIMER_SCOPE(thread, parser_timer); | 1071 CSTAT_TIMER_SCOPE(thread, parser_timer); |
1121 INC_STAT(thread, num_functions_parsed, 1); | 1072 INC_STAT(thread, num_functions_parsed, 1); |
1122 #ifndef PRODUCT | 1073 #ifndef PRODUCT |
1123 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 1074 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
1124 FLAG_profile_vm); | 1075 FLAG_profile_vm); |
1125 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 1076 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 ((instantiator != NULL) && instantiator->is_captured())) { | 1165 ((instantiator != NULL) && instantiator->is_captured())) { |
1215 parsed_function->set_instantiator(instantiator); | 1166 parsed_function->set_instantiator(instantiator); |
1216 } | 1167 } |
1217 } | 1168 } |
1218 // ParseFunc has recorded the generic function type arguments variable. | 1169 // ParseFunc has recorded the generic function type arguments variable. |
1219 ASSERT(!FLAG_reify_generic_functions || | 1170 ASSERT(!FLAG_reify_generic_functions || |
1220 !parser.current_function().IsGeneric() || | 1171 !parser.current_function().IsGeneric() || |
1221 (parsed_function->function_type_arguments() != NULL)); | 1172 (parsed_function->function_type_arguments() != NULL)); |
1222 } | 1173 } |
1223 | 1174 |
1224 | |
1225 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 1175 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
1226 LongJumpScope jump; | 1176 LongJumpScope jump; |
1227 if (setjmp(*jump.Set()) == 0) { | 1177 if (setjmp(*jump.Set()) == 0) { |
1228 Thread* thread = Thread::Current(); | 1178 Thread* thread = Thread::Current(); |
1229 StackZone stack_zone(thread); | 1179 StackZone stack_zone(thread); |
1230 Zone* zone = stack_zone.GetZone(); | 1180 Zone* zone = stack_zone.GetZone(); |
1231 const Class& owner_class = Class::Handle(zone, meta_data.Owner()); | 1181 const Class& owner_class = Class::Handle(zone, meta_data.Owner()); |
1232 const Script& script = Script::Handle(zone, meta_data.Script()); | 1182 const Script& script = Script::Handle(zone, meta_data.Script()); |
1233 const TokenPosition token_pos = meta_data.token_pos(); | 1183 const TokenPosition token_pos = meta_data.token_pos(); |
1234 // Parsing metadata can involve following paths in the parser that are | 1184 // Parsing metadata can involve following paths in the parser that are |
(...skipping 23 matching lines...) Expand all Loading... |
1258 Zone* zone = stack_zone.GetZone(); | 1208 Zone* zone = stack_zone.GetZone(); |
1259 Error& error = Error::Handle(zone); | 1209 Error& error = Error::Handle(zone); |
1260 error = thread->sticky_error(); | 1210 error = thread->sticky_error(); |
1261 thread->clear_sticky_error(); | 1211 thread->clear_sticky_error(); |
1262 return error.raw(); | 1212 return error.raw(); |
1263 } | 1213 } |
1264 UNREACHABLE(); | 1214 UNREACHABLE(); |
1265 return Object::null(); | 1215 return Object::null(); |
1266 } | 1216 } |
1267 | 1217 |
1268 | |
1269 RawArray* Parser::EvaluateMetadata() { | 1218 RawArray* Parser::EvaluateMetadata() { |
1270 CheckToken(Token::kAT, "Metadata character '@' expected"); | 1219 CheckToken(Token::kAT, "Metadata character '@' expected"); |
1271 GrowableObjectArray& meta_values = | 1220 GrowableObjectArray& meta_values = |
1272 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 1221 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
1273 while (CurrentToken() == Token::kAT) { | 1222 while (CurrentToken() == Token::kAT) { |
1274 ConsumeToken(); | 1223 ConsumeToken(); |
1275 TokenPosition expr_pos = TokenPos(); | 1224 TokenPosition expr_pos = TokenPos(); |
1276 if (!IsIdentifier()) { | 1225 if (!IsIdentifier()) { |
1277 ExpectIdentifier("identifier expected"); | 1226 ExpectIdentifier("identifier expected"); |
1278 } | 1227 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 } | 1281 } |
1333 if (expr->EvalConstExpr() == NULL) { | 1282 if (expr->EvalConstExpr() == NULL) { |
1334 ReportError(expr_pos, "expression must be a compile-time constant"); | 1283 ReportError(expr_pos, "expression must be a compile-time constant"); |
1335 } | 1284 } |
1336 const Instance& val = EvaluateConstExpr(expr_pos, expr); | 1285 const Instance& val = EvaluateConstExpr(expr_pos, expr); |
1337 meta_values.Add(val, Heap::kOld); | 1286 meta_values.Add(val, Heap::kOld); |
1338 } | 1287 } |
1339 return Array::MakeFixedLength(meta_values); | 1288 return Array::MakeFixedLength(meta_values); |
1340 } | 1289 } |
1341 | 1290 |
1342 | |
1343 SequenceNode* Parser::ParseStaticInitializer() { | 1291 SequenceNode* Parser::ParseStaticInitializer() { |
1344 ExpectIdentifier("field name expected"); | 1292 ExpectIdentifier("field name expected"); |
1345 CheckToken(Token::kASSIGN, "field initialier expected"); | 1293 CheckToken(Token::kASSIGN, "field initialier expected"); |
1346 ConsumeToken(); | 1294 ConsumeToken(); |
1347 OpenFunctionBlock(parsed_function()->function()); | 1295 OpenFunctionBlock(parsed_function()->function()); |
1348 TokenPosition expr_pos = TokenPos(); | 1296 TokenPosition expr_pos = TokenPos(); |
1349 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1297 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
1350 ReturnNode* ret = new (Z) ReturnNode(expr_pos, expr); | 1298 ReturnNode* ret = new (Z) ReturnNode(expr_pos, expr); |
1351 current_block_->statements->Add(ret); | 1299 current_block_->statements->Add(ret); |
1352 return CloseBlock(); | 1300 return CloseBlock(); |
1353 } | 1301 } |
1354 | 1302 |
1355 | |
1356 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1303 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
1357 ASSERT(field.is_static()); | 1304 ASSERT(field.is_static()); |
1358 Thread* thread = Thread::Current(); | 1305 Thread* thread = Thread::Current(); |
1359 // TODO(koda): Should there be a StackZone here? | 1306 // TODO(koda): Should there be a StackZone here? |
1360 Zone* zone = thread->zone(); | 1307 Zone* zone = thread->zone(); |
1361 #ifndef PRODUCT | 1308 #ifndef PRODUCT |
1362 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 1309 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
1363 FLAG_profile_vm); | 1310 FLAG_profile_vm); |
1364 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 1311 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
1365 "ParseStaticFieldInitializer"); | 1312 "ParseStaticFieldInitializer"); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 body->scope()->AddVariable(parsed_function->current_context_var()); | 1349 body->scope()->AddVariable(parsed_function->current_context_var()); |
1403 if (parsed_function->has_finally_return_temp_var()) { | 1350 if (parsed_function->has_finally_return_temp_var()) { |
1404 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); | 1351 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); |
1405 } | 1352 } |
1406 // The instantiator is not required in a static expression. | 1353 // The instantiator is not required in a static expression. |
1407 ASSERT(!parser.IsInstantiatorRequired()); | 1354 ASSERT(!parser.IsInstantiatorRequired()); |
1408 | 1355 |
1409 return parsed_function; | 1356 return parsed_function; |
1410 } | 1357 } |
1411 | 1358 |
1412 | |
1413 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 1359 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
1414 TRACE_PARSER("ParseStaticFinalGetter"); | 1360 TRACE_PARSER("ParseStaticFinalGetter"); |
1415 ASSERT(func.num_fixed_parameters() == 0); // static. | 1361 ASSERT(func.num_fixed_parameters() == 0); // static. |
1416 ASSERT(!func.HasOptionalParameters()); | 1362 ASSERT(!func.HasOptionalParameters()); |
1417 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1363 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
1418 OpenFunctionBlock(func); | 1364 OpenFunctionBlock(func); |
1419 TokenPosition ident_pos = TokenPos(); | 1365 TokenPosition ident_pos = TokenPos(); |
1420 const String& field_name = *ExpectIdentifier("field name expected"); | 1366 const String& field_name = *ExpectIdentifier("field name expected"); |
1421 const Class& field_class = Class::Handle(Z, func.Owner()); | 1367 const Class& field_class = Class::Handle(Z, func.Owner()); |
1422 const Field& field = | 1368 const Field& field = |
(...skipping 24 matching lines...) Expand all Loading... |
1447 // and handle errors while evaluating the expression. | 1393 // and handle errors while evaluating the expression. |
1448 current_block_->statements->Add(new (Z) | 1394 current_block_->statements->Add(new (Z) |
1449 InitStaticFieldNode(ident_pos, field)); | 1395 InitStaticFieldNode(ident_pos, field)); |
1450 ReturnNode* return_node = | 1396 ReturnNode* return_node = |
1451 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); | 1397 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); |
1452 current_block_->statements->Add(return_node); | 1398 current_block_->statements->Add(return_node); |
1453 } | 1399 } |
1454 return CloseBlock(); | 1400 return CloseBlock(); |
1455 } | 1401 } |
1456 | 1402 |
1457 | |
1458 // Create AstNodes for an implicit instance getter method: | 1403 // Create AstNodes for an implicit instance getter method: |
1459 // LoadLocalNode 0 ('this'); | 1404 // LoadLocalNode 0 ('this'); |
1460 // LoadInstanceFieldNode (field_name); | 1405 // LoadInstanceFieldNode (field_name); |
1461 // ReturnNode (field's value); | 1406 // ReturnNode (field's value); |
1462 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1407 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
1463 TRACE_PARSER("ParseInstanceGetter"); | 1408 TRACE_PARSER("ParseInstanceGetter"); |
1464 ParamList params; | 1409 ParamList params; |
1465 // func.token_pos() points to the name of the field. | 1410 // func.token_pos() points to the name of the field. |
1466 const TokenPosition ident_pos = func.token_pos(); | 1411 const TokenPosition ident_pos = func.token_pos(); |
1467 ASSERT(current_class().raw() == func.Owner()); | 1412 ASSERT(current_class().raw() == func.Owner()); |
(...skipping 18 matching lines...) Expand all Loading... |
1486 ASSERT(!field.IsNull()); | 1431 ASSERT(!field.IsNull()); |
1487 | 1432 |
1488 LoadInstanceFieldNode* load_field = | 1433 LoadInstanceFieldNode* load_field = |
1489 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1434 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
1490 | 1435 |
1491 ReturnNode* return_node = new ReturnNode(ST(ident_pos), load_field); | 1436 ReturnNode* return_node = new ReturnNode(ST(ident_pos), load_field); |
1492 current_block_->statements->Add(return_node); | 1437 current_block_->statements->Add(return_node); |
1493 return CloseBlock(); | 1438 return CloseBlock(); |
1494 } | 1439 } |
1495 | 1440 |
1496 | |
1497 // Create AstNodes for an implicit instance setter method: | 1441 // Create AstNodes for an implicit instance setter method: |
1498 // LoadLocalNode 0 ('this') | 1442 // LoadLocalNode 0 ('this') |
1499 // LoadLocalNode 1 ('value') | 1443 // LoadLocalNode 1 ('value') |
1500 // SetInstanceField (field_name); | 1444 // SetInstanceField (field_name); |
1501 // ReturnNode (void); | 1445 // ReturnNode (void); |
1502 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 1446 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
1503 TRACE_PARSER("ParseInstanceSetter"); | 1447 TRACE_PARSER("ParseInstanceSetter"); |
1504 // func.token_pos() points to the name of the field. | 1448 // func.token_pos() points to the name of the field. |
1505 const TokenPosition ident_pos = func.token_pos(); | 1449 const TokenPosition ident_pos = func.token_pos(); |
1506 const String& field_name = *CurrentLiteral(); | 1450 const String& field_name = *CurrentLiteral(); |
(...skipping 21 matching lines...) Expand all Loading... |
1528 | 1472 |
1529 EnsureExpressionTemp(); | 1473 EnsureExpressionTemp(); |
1530 StoreInstanceFieldNode* store_field = | 1474 StoreInstanceFieldNode* store_field = |
1531 new StoreInstanceFieldNode(ident_pos, receiver, field, value, | 1475 new StoreInstanceFieldNode(ident_pos, receiver, field, value, |
1532 /* is_initializer = */ false); | 1476 /* is_initializer = */ false); |
1533 current_block_->statements->Add(store_field); | 1477 current_block_->statements->Add(store_field); |
1534 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); | 1478 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); |
1535 return CloseBlock(); | 1479 return CloseBlock(); |
1536 } | 1480 } |
1537 | 1481 |
1538 | |
1539 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { | 1482 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { |
1540 TRACE_PARSER("ParseConstructorClosure"); | 1483 TRACE_PARSER("ParseConstructorClosure"); |
1541 const TokenPosition token_pos = func.token_pos(); | 1484 const TokenPosition token_pos = func.token_pos(); |
1542 | 1485 |
1543 Function& constructor = Function::ZoneHandle(Z); | 1486 Function& constructor = Function::ZoneHandle(Z); |
1544 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1487 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
1545 ParseConstructorClosurization(&constructor, &type_args); | 1488 ParseConstructorClosurization(&constructor, &type_args); |
1546 ASSERT(!constructor.IsNull()); | 1489 ASSERT(!constructor.IsNull()); |
1547 | 1490 |
1548 ParamList params; | 1491 ParamList params; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1581 ctor_args->set_names(arg_names); | 1524 ctor_args->set_names(arg_names); |
1582 } | 1525 } |
1583 | 1526 |
1584 AstNode* new_object = | 1527 AstNode* new_object = |
1585 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); | 1528 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); |
1586 ReturnNode* return_node = new ReturnNode(token_pos, new_object); | 1529 ReturnNode* return_node = new ReturnNode(token_pos, new_object); |
1587 current_block_->statements->Add(return_node); | 1530 current_block_->statements->Add(return_node); |
1588 return CloseBlock(); | 1531 return CloseBlock(); |
1589 } | 1532 } |
1590 | 1533 |
1591 | |
1592 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { | 1534 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { |
1593 TRACE_PARSER("ParseImplicitClosure"); | 1535 TRACE_PARSER("ParseImplicitClosure"); |
1594 TokenPosition token_pos = func.token_pos(); | 1536 TokenPosition token_pos = func.token_pos(); |
1595 | 1537 |
1596 OpenFunctionBlock(func); | 1538 OpenFunctionBlock(func); |
1597 | 1539 |
1598 const Function& parent = Function::Handle(func.parent_function()); | 1540 const Function& parent = Function::Handle(func.parent_function()); |
1599 intptr_t type_args_len = 0; // Length of type args vector passed to parent. | 1541 intptr_t type_args_len = 0; // Length of type args vector passed to parent. |
1600 LocalVariable* type_args_var = NULL; | 1542 LocalVariable* type_args_var = NULL; |
1601 if (FLAG_reify_generic_functions) { | 1543 if (FLAG_reify_generic_functions) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 InvocationMirror::kStatic, im_type, | 1670 InvocationMirror::kStatic, im_type, |
1729 NULL); // No existing function. | 1671 NULL); // No existing function. |
1730 } | 1672 } |
1731 | 1673 |
1732 ASSERT(call != NULL); | 1674 ASSERT(call != NULL); |
1733 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1675 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1734 current_block_->statements->Add(return_node); | 1676 current_block_->statements->Add(return_node); |
1735 return CloseBlock(); | 1677 return CloseBlock(); |
1736 } | 1678 } |
1737 | 1679 |
1738 | |
1739 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1680 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
1740 TRACE_PARSER("ParseMethodExtractor"); | 1681 TRACE_PARSER("ParseMethodExtractor"); |
1741 | 1682 |
1742 ParamList params; | 1683 ParamList params; |
1743 | 1684 |
1744 const TokenPosition ident_pos = func.token_pos(); | 1685 const TokenPosition ident_pos = func.token_pos(); |
1745 ASSERT(func.token_pos() == TokenPosition::kMethodExtractor); | 1686 ASSERT(func.token_pos() == TokenPosition::kMethodExtractor); |
1746 ASSERT(current_class().raw() == func.Owner()); | 1687 ASSERT(current_class().raw() == func.Owner()); |
1747 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1688 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1748 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1689 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
1749 ASSERT(!func.HasOptionalParameters()); | 1690 ASSERT(!func.HasOptionalParameters()); |
1750 | 1691 |
1751 // Build local scope for function and populate with the formal parameters. | 1692 // Build local scope for function and populate with the formal parameters. |
1752 OpenFunctionBlock(func); | 1693 OpenFunctionBlock(func); |
1753 AddFormalParamsToScope(¶ms, current_block_->scope); | 1694 AddFormalParamsToScope(¶ms, current_block_->scope); |
1754 | 1695 |
1755 // Receiver is local 0. | 1696 // Receiver is local 0. |
1756 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1697 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1757 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1698 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
1758 | 1699 |
1759 ClosureNode* closure = new ClosureNode( | 1700 ClosureNode* closure = new ClosureNode( |
1760 ident_pos, Function::ZoneHandle(Z, func.extracted_method_closure()), | 1701 ident_pos, Function::ZoneHandle(Z, func.extracted_method_closure()), |
1761 load_receiver, NULL); | 1702 load_receiver, NULL); |
1762 | 1703 |
1763 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1704 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
1764 current_block_->statements->Add(return_node); | 1705 current_block_->statements->Add(return_node); |
1765 return CloseBlock(); | 1706 return CloseBlock(); |
1766 } | 1707 } |
1767 | 1708 |
1768 | |
1769 void Parser::BuildDispatcherScope(const Function& func, | 1709 void Parser::BuildDispatcherScope(const Function& func, |
1770 const ArgumentsDescriptor& desc) { | 1710 const ArgumentsDescriptor& desc) { |
1771 ParamList params; | 1711 ParamList params; |
1772 // Receiver first. | 1712 // Receiver first. |
1773 TokenPosition token_pos = func.token_pos(); | 1713 TokenPosition token_pos = func.token_pos(); |
1774 params.AddReceiver(ReceiverType(current_class()), token_pos); | 1714 params.AddReceiver(ReceiverType(current_class()), token_pos); |
1775 // Remaining positional parameters. | 1715 // Remaining positional parameters. |
1776 intptr_t i = 1; | 1716 intptr_t i = 1; |
1777 for (; i < desc.PositionalCount(); ++i) { | 1717 for (; i < desc.PositionalCount(); ++i) { |
1778 ParamDesc p; | 1718 ParamDesc p; |
(...skipping 30 matching lines...) Expand all Loading... |
1809 // Insert function type arguments variable to scope. | 1749 // Insert function type arguments variable to scope. |
1810 LocalVariable* type_args_var = new (Z) LocalVariable( | 1750 LocalVariable* type_args_var = new (Z) LocalVariable( |
1811 TokenPosition::kNoSource, TokenPosition::kNoSource, | 1751 TokenPosition::kNoSource, TokenPosition::kNoSource, |
1812 Symbols::FunctionTypeArgumentsVar(), Object::dynamic_type()); | 1752 Symbols::FunctionTypeArgumentsVar(), Object::dynamic_type()); |
1813 current_block_->scope->AddVariable(type_args_var); | 1753 current_block_->scope->AddVariable(type_args_var); |
1814 ASSERT(FunctionLevel() == 0); | 1754 ASSERT(FunctionLevel() == 0); |
1815 parsed_function_->set_function_type_arguments(type_args_var); | 1755 parsed_function_->set_function_type_arguments(type_args_var); |
1816 } | 1756 } |
1817 } | 1757 } |
1818 | 1758 |
1819 | |
1820 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { | 1759 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { |
1821 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1760 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
1822 ASSERT(FLAG_lazy_dispatchers); | 1761 ASSERT(FLAG_lazy_dispatchers); |
1823 ASSERT(func.IsNoSuchMethodDispatcher()); | 1762 ASSERT(func.IsNoSuchMethodDispatcher()); |
1824 TokenPosition token_pos = func.token_pos(); | 1763 TokenPosition token_pos = func.token_pos(); |
1825 ASSERT(func.token_pos() == TokenPosition::kMinSource); | 1764 ASSERT(func.token_pos() == TokenPosition::kMinSource); |
1826 ASSERT(current_class().raw() == func.Owner()); | 1765 ASSERT(current_class().raw() == func.Owner()); |
1827 | 1766 |
1828 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); | 1767 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); |
1829 ASSERT(desc.Count() > 0); | 1768 ASSERT(desc.Count() > 0); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 Symbols::NoSuchMethod(), args_desc); | 1806 Symbols::NoSuchMethod(), args_desc); |
1868 } | 1807 } |
1869 StaticCallNode* call = | 1808 StaticCallNode* call = |
1870 new StaticCallNode(token_pos, no_such_method, arguments); | 1809 new StaticCallNode(token_pos, no_such_method, arguments); |
1871 | 1810 |
1872 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1811 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1873 current_block_->statements->Add(return_node); | 1812 current_block_->statements->Add(return_node); |
1874 return CloseBlock(); | 1813 return CloseBlock(); |
1875 } | 1814 } |
1876 | 1815 |
1877 | |
1878 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { | 1816 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { |
1879 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1817 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
1880 ASSERT(func.IsInvokeFieldDispatcher()); | 1818 ASSERT(func.IsInvokeFieldDispatcher()); |
1881 TokenPosition token_pos = func.token_pos(); | 1819 TokenPosition token_pos = func.token_pos(); |
1882 ASSERT(func.token_pos() == TokenPosition::kMinSource); | 1820 ASSERT(func.token_pos() == TokenPosition::kMinSource); |
1883 ASSERT(current_class().raw() == func.Owner()); | 1821 ASSERT(current_class().raw() == func.Owner()); |
1884 | 1822 |
1885 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); | 1823 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
1886 ArgumentsDescriptor desc(args_desc); | 1824 ArgumentsDescriptor desc(args_desc); |
1887 ASSERT(desc.Count() > 0); | 1825 ASSERT(desc.Count() > 0); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 result = new ClosureCallNode(token_pos, function_object, args); | 1873 result = new ClosureCallNode(token_pos, function_object, args); |
1936 } else { | 1874 } else { |
1937 result = BuildClosureCall(token_pos, function_object, args); | 1875 result = BuildClosureCall(token_pos, function_object, args); |
1938 } | 1876 } |
1939 | 1877 |
1940 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1878 ReturnNode* return_node = new ReturnNode(token_pos, result); |
1941 current_block_->statements->Add(return_node); | 1879 current_block_->statements->Add(return_node); |
1942 return CloseBlock(); | 1880 return CloseBlock(); |
1943 } | 1881 } |
1944 | 1882 |
1945 | |
1946 AstNode* Parser::BuildClosureCall(TokenPosition token_pos, | 1883 AstNode* Parser::BuildClosureCall(TokenPosition token_pos, |
1947 AstNode* closure, | 1884 AstNode* closure, |
1948 ArgumentListNode* arguments) { | 1885 ArgumentListNode* arguments) { |
1949 return new InstanceCallNode(token_pos, closure, Symbols::Call(), arguments); | 1886 return new InstanceCallNode(token_pos, closure, Symbols::Call(), arguments); |
1950 } | 1887 } |
1951 | 1888 |
1952 | |
1953 void Parser::SkipToMatching() { | 1889 void Parser::SkipToMatching() { |
1954 Token::Kind opening_token = CurrentToken(); | 1890 Token::Kind opening_token = CurrentToken(); |
1955 ASSERT((opening_token == Token::kLBRACE) || | 1891 ASSERT((opening_token == Token::kLBRACE) || |
1956 (opening_token == Token::kLPAREN)); | 1892 (opening_token == Token::kLPAREN)); |
1957 GrowableArray<Token::Kind> token_stack(8); | 1893 GrowableArray<Token::Kind> token_stack(8); |
1958 GrowableArray<TokenPosition> token_pos_stack(8); | 1894 GrowableArray<TokenPosition> token_pos_stack(8); |
1959 // Adding the first opening brace here, because it will be consumed | 1895 // Adding the first opening brace here, because it will be consumed |
1960 // in the loop right away. | 1896 // in the loop right away. |
1961 token_stack.Add(opening_token); | 1897 token_stack.Add(opening_token); |
1962 const TokenPosition start_pos = TokenPos(); | 1898 const TokenPosition start_pos = TokenPos(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2007 Error::Handle(), script_, opening_pos, Report::AtLocation, | 1943 Error::Handle(), script_, opening_pos, Report::AtLocation, |
2008 Report::kWarning, allocation_space_, "unbalanced '%s' opens here", | 1944 Report::kWarning, allocation_space_, "unbalanced '%s' opens here", |
2009 Token::Str(opening_token))); | 1945 Token::Str(opening_token))); |
2010 ReportErrors(error, script_, token_pos, "unbalanced '%s'", | 1946 ReportErrors(error, script_, token_pos, "unbalanced '%s'", |
2011 Token::Str(token)); | 1947 Token::Str(token)); |
2012 } else if (unexpected_token_found) { | 1948 } else if (unexpected_token_found) { |
2013 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); | 1949 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); |
2014 } | 1950 } |
2015 } | 1951 } |
2016 | 1952 |
2017 | |
2018 void Parser::SkipBlock() { | 1953 void Parser::SkipBlock() { |
2019 ASSERT(CurrentToken() == Token::kLBRACE); | 1954 ASSERT(CurrentToken() == Token::kLBRACE); |
2020 SkipToMatching(); | 1955 SkipToMatching(); |
2021 } | 1956 } |
2022 | 1957 |
2023 | |
2024 // Skips tokens up to and including matching closing parenthesis. | 1958 // Skips tokens up to and including matching closing parenthesis. |
2025 void Parser::SkipToMatchingParenthesis() { | 1959 void Parser::SkipToMatchingParenthesis() { |
2026 ASSERT(CurrentToken() == Token::kLPAREN); | 1960 ASSERT(CurrentToken() == Token::kLPAREN); |
2027 SkipToMatching(); | 1961 SkipToMatching(); |
2028 ASSERT(CurrentToken() == Token::kRPAREN); | 1962 ASSERT(CurrentToken() == Token::kRPAREN); |
2029 ConsumeToken(); | 1963 ConsumeToken(); |
2030 } | 1964 } |
2031 | 1965 |
2032 | |
2033 // Parses a parameter type as defined by the 'parameterTypeList' production. | 1966 // Parses a parameter type as defined by the 'parameterTypeList' production. |
2034 void Parser::ParseParameterType(ParamList* params) { | 1967 void Parser::ParseParameterType(ParamList* params) { |
2035 TRACE_PARSER("ParseParameterType"); | 1968 TRACE_PARSER("ParseParameterType"); |
2036 ParamDesc parameter; | 1969 ParamDesc parameter; |
2037 | 1970 |
2038 parameter.has_explicit_type = true; // The type is required by the syntax. | 1971 parameter.has_explicit_type = true; // The type is required by the syntax. |
2039 // It is too early to resolve the type here, since it can be a result type | 1972 // It is too early to resolve the type here, since it can be a result type |
2040 // referring to a not yet declared function type parameter. | 1973 // referring to a not yet declared function type parameter. |
2041 parameter.type = &AbstractType::ZoneHandle( | 1974 parameter.type = &AbstractType::ZoneHandle( |
2042 Z, ParseTypeOrFunctionType(false, ClassFinalizer::kDoNotResolve)); | 1975 Z, ParseTypeOrFunctionType(false, ClassFinalizer::kDoNotResolve)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2093 } | 2026 } |
2094 if (params->implicitly_final) { | 2027 if (params->implicitly_final) { |
2095 parameter.is_final = true; | 2028 parameter.is_final = true; |
2096 } | 2029 } |
2097 params->parameters->Add(parameter); | 2030 params->parameters->Add(parameter); |
2098 if (parameter.is_covariant) { | 2031 if (parameter.is_covariant) { |
2099 params->has_covariant = true; | 2032 params->has_covariant = true; |
2100 } | 2033 } |
2101 } | 2034 } |
2102 | 2035 |
2103 | |
2104 // Parses a formal parameter as defined by the 'formalParameterList' production. | 2036 // Parses a formal parameter as defined by the 'formalParameterList' production. |
2105 void Parser::ParseFormalParameter(bool allow_explicit_default_value, | 2037 void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
2106 bool evaluate_metadata, | 2038 bool evaluate_metadata, |
2107 ParamList* params) { | 2039 ParamList* params) { |
2108 TRACE_PARSER("ParseFormalParameter"); | 2040 TRACE_PARSER("ParseFormalParameter"); |
2109 ParamDesc parameter; | 2041 ParamDesc parameter; |
2110 bool var_seen = false; | 2042 bool var_seen = false; |
2111 bool final_seen = false; | 2043 bool final_seen = false; |
2112 bool this_seen = false; | 2044 bool this_seen = false; |
2113 | 2045 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 } | 2256 } |
2325 if (params->implicitly_final) { | 2257 if (params->implicitly_final) { |
2326 parameter.is_final = true; | 2258 parameter.is_final = true; |
2327 } | 2259 } |
2328 params->parameters->Add(parameter); | 2260 params->parameters->Add(parameter); |
2329 if (parameter.is_covariant) { | 2261 if (parameter.is_covariant) { |
2330 params->has_covariant = true; | 2262 params->has_covariant = true; |
2331 } | 2263 } |
2332 } | 2264 } |
2333 | 2265 |
2334 | |
2335 // Parses a sequence of normal or optional formal parameters. | 2266 // Parses a sequence of normal or optional formal parameters. |
2336 void Parser::ParseFormalParameters(bool use_function_type_syntax, | 2267 void Parser::ParseFormalParameters(bool use_function_type_syntax, |
2337 bool allow_explicit_default_values, | 2268 bool allow_explicit_default_values, |
2338 bool evaluate_metadata, | 2269 bool evaluate_metadata, |
2339 ParamList* params) { | 2270 ParamList* params) { |
2340 TRACE_PARSER("ParseFormalParameters"); | 2271 TRACE_PARSER("ParseFormalParameters"); |
2341 // Optional parameter lists cannot be empty. | 2272 // Optional parameter lists cannot be empty. |
2342 // The completely empty parameter list is handled before getting here. | 2273 // The completely empty parameter list is handled before getting here. |
2343 bool has_seen_parameter = false; | 2274 bool has_seen_parameter = false; |
2344 do { | 2275 do { |
(...skipping 25 matching lines...) Expand all Loading... |
2370 ASSERT(!allow_explicit_default_values && !evaluate_metadata); | 2301 ASSERT(!allow_explicit_default_values && !evaluate_metadata); |
2371 ParseParameterType(params); | 2302 ParseParameterType(params); |
2372 } else { | 2303 } else { |
2373 ParseFormalParameter(allow_explicit_default_values, evaluate_metadata, | 2304 ParseFormalParameter(allow_explicit_default_values, evaluate_metadata, |
2374 params); | 2305 params); |
2375 } | 2306 } |
2376 has_seen_parameter = true; | 2307 has_seen_parameter = true; |
2377 } while (CurrentToken() == Token::kCOMMA); | 2308 } while (CurrentToken() == Token::kCOMMA); |
2378 } | 2309 } |
2379 | 2310 |
2380 | |
2381 void Parser::ParseFormalParameterList(bool use_function_type_syntax, | 2311 void Parser::ParseFormalParameterList(bool use_function_type_syntax, |
2382 bool allow_explicit_default_values, | 2312 bool allow_explicit_default_values, |
2383 bool evaluate_metadata, | 2313 bool evaluate_metadata, |
2384 ParamList* params) { | 2314 ParamList* params) { |
2385 TRACE_PARSER("ParseFormalParameterList"); | 2315 TRACE_PARSER("ParseFormalParameterList"); |
2386 ASSERT(CurrentToken() == Token::kLPAREN); | 2316 ASSERT(CurrentToken() == Token::kLPAREN); |
2387 | 2317 |
2388 if (LookaheadToken(1) != Token::kRPAREN) { | 2318 if (LookaheadToken(1) != Token::kRPAREN) { |
2389 // Parse fixed parameters. | 2319 // Parse fixed parameters. |
2390 ParseFormalParameters(use_function_type_syntax, | 2320 ParseFormalParameters(use_function_type_syntax, |
(...skipping 16 matching lines...) Expand all Loading... |
2407 !params->has_optional_positional_parameters && | 2337 !params->has_optional_positional_parameters && |
2408 !params->has_optional_named_parameters) { | 2338 !params->has_optional_named_parameters) { |
2409 ReportError("',' or ')' expected"); | 2339 ReportError("',' or ')' expected"); |
2410 } | 2340 } |
2411 } else { | 2341 } else { |
2412 ConsumeToken(); | 2342 ConsumeToken(); |
2413 } | 2343 } |
2414 ExpectToken(Token::kRPAREN); | 2344 ExpectToken(Token::kRPAREN); |
2415 } | 2345 } |
2416 | 2346 |
2417 | |
2418 String& Parser::ParseNativeDeclaration() { | 2347 String& Parser::ParseNativeDeclaration() { |
2419 TRACE_PARSER("ParseNativeDeclaration"); | 2348 TRACE_PARSER("ParseNativeDeclaration"); |
2420 ASSERT(IsSymbol(Symbols::Native())); | 2349 ASSERT(IsSymbol(Symbols::Native())); |
2421 ConsumeToken(); | 2350 ConsumeToken(); |
2422 CheckToken(Token::kSTRING, "string literal expected"); | 2351 CheckToken(Token::kSTRING, "string literal expected"); |
2423 String& native_name = *CurrentLiteral(); | 2352 String& native_name = *CurrentLiteral(); |
2424 ConsumeToken(); | 2353 ConsumeToken(); |
2425 return native_name; | 2354 return native_name; |
2426 } | 2355 } |
2427 | 2356 |
2428 | |
2429 // Resolve and return the dynamic function of the given name in the superclass. | 2357 // Resolve and return the dynamic function of the given name in the superclass. |
2430 // If it is not found, and resolve_getter is true, try to resolve a getter of | 2358 // If it is not found, and resolve_getter is true, try to resolve a getter of |
2431 // the same name. If it is still not found, return noSuchMethod and | 2359 // the same name. If it is still not found, return noSuchMethod and |
2432 // set is_no_such_method to true.. | 2360 // set is_no_such_method to true.. |
2433 RawFunction* Parser::GetSuperFunction(TokenPosition token_pos, | 2361 RawFunction* Parser::GetSuperFunction(TokenPosition token_pos, |
2434 const String& name, | 2362 const String& name, |
2435 ArgumentListNode* arguments, | 2363 ArgumentListNode* arguments, |
2436 bool resolve_getter, | 2364 bool resolve_getter, |
2437 bool* is_no_such_method) { | 2365 bool* is_no_such_method) { |
2438 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); | 2366 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
(...skipping 21 matching lines...) Expand all Loading... |
2460 super_func = Resolver::ResolveDynamicAnyArgs(Z, super_class, | 2388 super_func = Resolver::ResolveDynamicAnyArgs(Z, super_class, |
2461 Symbols::NoSuchMethod()); | 2389 Symbols::NoSuchMethod()); |
2462 ASSERT(!super_func.IsNull()); | 2390 ASSERT(!super_func.IsNull()); |
2463 *is_no_such_method = true; | 2391 *is_no_such_method = true; |
2464 } else { | 2392 } else { |
2465 *is_no_such_method = false; | 2393 *is_no_such_method = false; |
2466 } | 2394 } |
2467 return super_func.raw(); | 2395 return super_func.raw(); |
2468 } | 2396 } |
2469 | 2397 |
2470 | |
2471 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 2398 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
2472 TokenPosition call_pos, | 2399 TokenPosition call_pos, |
2473 const String& function_name, | 2400 const String& function_name, |
2474 const ArgumentListNode& function_args, | 2401 const ArgumentListNode& function_args, |
2475 const LocalVariable* temp_for_last_arg, | 2402 const LocalVariable* temp_for_last_arg, |
2476 bool is_super_invocation) { | 2403 bool is_super_invocation) { |
2477 const TokenPosition args_pos = function_args.token_pos(); | 2404 const TokenPosition args_pos = function_args.token_pos(); |
2478 // Build arguments to the call to the static | 2405 // Build arguments to the call to the static |
2479 // InvocationMirror._allocateInvocationMirror method. | 2406 // InvocationMirror._allocateInvocationMirror method. |
2480 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2407 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2514 const Class& mirror_class = | 2441 const Class& mirror_class = |
2515 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); | 2442 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); |
2516 ASSERT(!mirror_class.IsNull()); | 2443 ASSERT(!mirror_class.IsNull()); |
2517 const Function& allocation_function = | 2444 const Function& allocation_function = |
2518 Function::ZoneHandle(mirror_class.LookupStaticFunction( | 2445 Function::ZoneHandle(mirror_class.LookupStaticFunction( |
2519 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); | 2446 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); |
2520 ASSERT(!allocation_function.IsNull()); | 2447 ASSERT(!allocation_function.IsNull()); |
2521 return new StaticCallNode(call_pos, allocation_function, arguments); | 2448 return new StaticCallNode(call_pos, allocation_function, arguments); |
2522 } | 2449 } |
2523 | 2450 |
2524 | |
2525 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 2451 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
2526 TokenPosition call_pos, | 2452 TokenPosition call_pos, |
2527 const String& function_name, | 2453 const String& function_name, |
2528 const ArgumentListNode& function_args, | 2454 const ArgumentListNode& function_args, |
2529 const LocalVariable* temp_for_last_arg, | 2455 const LocalVariable* temp_for_last_arg, |
2530 bool is_super_invocation) { | 2456 bool is_super_invocation) { |
2531 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 2457 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
2532 const TokenPosition args_pos = function_args.token_pos(); | 2458 const TokenPosition args_pos = function_args.token_pos(); |
2533 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2459 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
2534 arguments->Add(function_args.NodeAt(0)); | 2460 arguments->Add(function_args.NodeAt(0)); |
2535 // The second argument is the invocation mirror. | 2461 // The second argument is the invocation mirror. |
2536 arguments->Add( | 2462 arguments->Add( |
2537 BuildInvocationMirrorAllocation(call_pos, function_name, function_args, | 2463 BuildInvocationMirrorAllocation(call_pos, function_name, function_args, |
2538 temp_for_last_arg, is_super_invocation)); | 2464 temp_for_last_arg, is_super_invocation)); |
2539 return arguments; | 2465 return arguments; |
2540 } | 2466 } |
2541 | 2467 |
2542 | |
2543 AstNode* Parser::ParseSuperCall(const String& function_name, | 2468 AstNode* Parser::ParseSuperCall(const String& function_name, |
2544 const TypeArguments& func_type_args) { | 2469 const TypeArguments& func_type_args) { |
2545 TRACE_PARSER("ParseSuperCall"); | 2470 TRACE_PARSER("ParseSuperCall"); |
2546 ASSERT(CurrentToken() == Token::kLPAREN); | 2471 ASSERT(CurrentToken() == Token::kLPAREN); |
2547 const TokenPosition supercall_pos = TokenPos(); | 2472 const TokenPosition supercall_pos = TokenPos(); |
2548 | 2473 |
2549 // 'this' parameter is the first argument to super call (after the type args). | 2474 // 'this' parameter is the first argument to super call (after the type args). |
2550 ArgumentListNode* arguments = | 2475 ArgumentListNode* arguments = |
2551 new ArgumentListNode(supercall_pos, func_type_args); | 2476 new ArgumentListNode(supercall_pos, func_type_args); |
2552 AstNode* receiver = LoadReceiver(supercall_pos); | 2477 AstNode* receiver = LoadReceiver(supercall_pos); |
(...skipping 19 matching lines...) Expand all Loading... |
2572 } | 2497 } |
2573 return BuildClosureCall(supercall_pos, closure, closure_arguments); | 2498 return BuildClosureCall(supercall_pos, closure, closure_arguments); |
2574 } | 2499 } |
2575 if (is_no_such_method) { | 2500 if (is_no_such_method) { |
2576 arguments = BuildNoSuchMethodArguments(supercall_pos, function_name, | 2501 arguments = BuildNoSuchMethodArguments(supercall_pos, function_name, |
2577 *arguments, NULL, true); | 2502 *arguments, NULL, true); |
2578 } | 2503 } |
2579 return new StaticCallNode(supercall_pos, super_function, arguments); | 2504 return new StaticCallNode(supercall_pos, super_function, arguments); |
2580 } | 2505 } |
2581 | 2506 |
2582 | |
2583 // Simple test if a node is side effect free. | 2507 // Simple test if a node is side effect free. |
2584 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 2508 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
2585 return node->IsLiteralNode() || node->IsLoadLocalNode(); | 2509 return node->IsLiteralNode() || node->IsLoadLocalNode(); |
2586 } | 2510 } |
2587 | 2511 |
2588 | |
2589 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 2512 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
2590 ASSERT(super->IsSuper()); | 2513 ASSERT(super->IsSuper()); |
2591 AstNode* super_op = NULL; | 2514 AstNode* super_op = NULL; |
2592 const TokenPosition super_pos = super->token_pos(); | 2515 const TokenPosition super_pos = super->token_pos(); |
2593 if ((op == Token::kNEGATE) || (op == Token::kBIT_NOT)) { | 2516 if ((op == Token::kNEGATE) || (op == Token::kBIT_NOT)) { |
2594 // Resolve the operator function in the superclass. | 2517 // Resolve the operator function in the superclass. |
2595 const String& operator_function_name = Symbols::Token(op); | 2518 const String& operator_function_name = Symbols::Token(op); |
2596 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 2519 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
2597 AstNode* receiver = LoadReceiver(super_pos); | 2520 AstNode* receiver = LoadReceiver(super_pos); |
2598 op_arguments->Add(receiver); | 2521 op_arguments->Add(receiver); |
2599 const bool kResolveGetter = false; | 2522 const bool kResolveGetter = false; |
2600 bool is_no_such_method = false; | 2523 bool is_no_such_method = false; |
2601 const Function& super_operator = Function::ZoneHandle( | 2524 const Function& super_operator = Function::ZoneHandle( |
2602 Z, GetSuperFunction(super_pos, operator_function_name, op_arguments, | 2525 Z, GetSuperFunction(super_pos, operator_function_name, op_arguments, |
2603 kResolveGetter, &is_no_such_method)); | 2526 kResolveGetter, &is_no_such_method)); |
2604 if (is_no_such_method) { | 2527 if (is_no_such_method) { |
2605 op_arguments = BuildNoSuchMethodArguments( | 2528 op_arguments = BuildNoSuchMethodArguments( |
2606 super_pos, operator_function_name, *op_arguments, NULL, true); | 2529 super_pos, operator_function_name, *op_arguments, NULL, true); |
2607 } | 2530 } |
2608 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 2531 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
2609 } else { | 2532 } else { |
2610 ReportError(super_pos, "illegal super operator call"); | 2533 ReportError(super_pos, "illegal super operator call"); |
2611 } | 2534 } |
2612 return super_op; | 2535 return super_op; |
2613 } | 2536 } |
2614 | 2537 |
2615 | |
2616 AstNode* Parser::ParseSuperOperator() { | 2538 AstNode* Parser::ParseSuperOperator() { |
2617 TRACE_PARSER("ParseSuperOperator"); | 2539 TRACE_PARSER("ParseSuperOperator"); |
2618 AstNode* super_op = NULL; | 2540 AstNode* super_op = NULL; |
2619 const TokenPosition operator_pos = TokenPos(); | 2541 const TokenPosition operator_pos = TokenPos(); |
2620 | 2542 |
2621 if (CurrentToken() == Token::kLBRACK) { | 2543 if (CurrentToken() == Token::kLBRACK) { |
2622 ConsumeToken(); | 2544 ConsumeToken(); |
2623 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2545 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2624 ExpectToken(Token::kRBRACK); | 2546 ExpectToken(Token::kRBRACK); |
2625 AstNode* receiver = LoadReceiver(operator_pos); | 2547 AstNode* receiver = LoadReceiver(operator_pos); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2660 operator_pos, operator_function_name, *op_arguments, NULL, true); | 2582 operator_pos, operator_function_name, *op_arguments, NULL, true); |
2661 } | 2583 } |
2662 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2584 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
2663 if (negate_result) { | 2585 if (negate_result) { |
2664 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2586 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
2665 } | 2587 } |
2666 } | 2588 } |
2667 return super_op; | 2589 return super_op; |
2668 } | 2590 } |
2669 | 2591 |
2670 | |
2671 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, | 2592 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
2672 TokenPosition token_pos, | 2593 TokenPosition token_pos, |
2673 AstNode* receiver) { | 2594 AstNode* receiver) { |
2674 Function& implicit_closure_function = | 2595 Function& implicit_closure_function = |
2675 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); | 2596 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); |
2676 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2597 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
2677 } | 2598 } |
2678 | 2599 |
2679 | |
2680 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2600 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
2681 TokenPosition field_pos) { | 2601 TokenPosition field_pos) { |
2682 TRACE_PARSER("ParseSuperFieldAccess"); | 2602 TRACE_PARSER("ParseSuperFieldAccess"); |
2683 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); | 2603 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); |
2684 if (super_class.IsNull()) { | 2604 if (super_class.IsNull()) { |
2685 ReportError("class '%s' does not have a superclass", | 2605 ReportError("class '%s' does not have a superclass", |
2686 String::Handle(Z, current_class().Name()).ToCString()); | 2606 String::Handle(Z, current_class().Name()).ToCString()); |
2687 } | 2607 } |
2688 AstNode* implicit_argument = LoadReceiver(field_pos); | 2608 AstNode* implicit_argument = LoadReceiver(field_pos); |
2689 | 2609 |
(...skipping 25 matching lines...) Expand all Loading... |
2715 implicit_argument); | 2635 implicit_argument); |
2716 } | 2636 } |
2717 // No function or field exists of the specified field_name. | 2637 // No function or field exists of the specified field_name. |
2718 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2638 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
2719 } | 2639 } |
2720 } | 2640 } |
2721 return new (Z) | 2641 return new (Z) |
2722 StaticGetterNode(field_pos, implicit_argument, super_class, field_name); | 2642 StaticGetterNode(field_pos, implicit_argument, super_class, field_name); |
2723 } | 2643 } |
2724 | 2644 |
2725 | |
2726 StaticCallNode* Parser::GenerateSuperConstructorCall( | 2645 StaticCallNode* Parser::GenerateSuperConstructorCall( |
2727 const Class& cls, | 2646 const Class& cls, |
2728 TokenPosition supercall_pos, | 2647 TokenPosition supercall_pos, |
2729 LocalVariable* receiver, | 2648 LocalVariable* receiver, |
2730 ArgumentListNode* forwarding_args) { | 2649 ArgumentListNode* forwarding_args) { |
2731 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2650 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2732 // Omit the implicit super() if there is no super class (i.e. | 2651 // Omit the implicit super() if there is no super class (i.e. |
2733 // we're not compiling class Object), or if the super class is an | 2652 // we're not compiling class Object), or if the super class is an |
2734 // artificially generated "wrapper class" that has no constructor. | 2653 // artificially generated "wrapper class" that has no constructor. |
2735 if (super_class.IsNull() || | 2654 if (super_class.IsNull() || |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2785 arguments->length(), arguments->names(), | 2704 arguments->length(), arguments->names(), |
2786 &error_message)) { | 2705 &error_message)) { |
2787 ReportError(supercall_pos, | 2706 ReportError(supercall_pos, |
2788 "invalid arguments passed to super constructor '%s()': %s", | 2707 "invalid arguments passed to super constructor '%s()': %s", |
2789 String::Handle(Z, super_class.Name()).ToCString(), | 2708 String::Handle(Z, super_class.Name()).ToCString(), |
2790 error_message.ToCString()); | 2709 error_message.ToCString()); |
2791 } | 2710 } |
2792 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2711 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2793 } | 2712 } |
2794 | 2713 |
2795 | |
2796 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, | 2714 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, |
2797 LocalVariable* receiver) { | 2715 LocalVariable* receiver) { |
2798 TRACE_PARSER("ParseSuperInitializer"); | 2716 TRACE_PARSER("ParseSuperInitializer"); |
2799 ASSERT(CurrentToken() == Token::kSUPER); | 2717 ASSERT(CurrentToken() == Token::kSUPER); |
2800 const TokenPosition supercall_pos = TokenPos(); | 2718 const TokenPosition supercall_pos = TokenPos(); |
2801 ConsumeToken(); | 2719 ConsumeToken(); |
2802 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2720 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2803 ASSERT(!super_class.IsNull()); | 2721 ASSERT(!super_class.IsNull()); |
2804 String& ctor_name = String::Handle(Z, super_class.Name()); | 2722 String& ctor_name = String::Handle(Z, super_class.Name()); |
2805 ctor_name = Symbols::FromConcat(T, ctor_name, Symbols::Dot()); | 2723 ctor_name = Symbols::FromConcat(T, ctor_name, Symbols::Dot()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2840 if (!super_ctor.AreValidArguments(arguments->type_args_len(), | 2758 if (!super_ctor.AreValidArguments(arguments->type_args_len(), |
2841 arguments->length(), arguments->names(), | 2759 arguments->length(), arguments->names(), |
2842 &error_message)) { | 2760 &error_message)) { |
2843 ReportError(supercall_pos, | 2761 ReportError(supercall_pos, |
2844 "invalid arguments passed to super class constructor '%s': %s", | 2762 "invalid arguments passed to super class constructor '%s': %s", |
2845 ctor_name.ToCString(), error_message.ToCString()); | 2763 ctor_name.ToCString(), error_message.ToCString()); |
2846 } | 2764 } |
2847 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2765 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2848 } | 2766 } |
2849 | 2767 |
2850 | |
2851 AstNode* Parser::ParseInitializer(const Class& cls, | 2768 AstNode* Parser::ParseInitializer(const Class& cls, |
2852 LocalVariable* receiver, | 2769 LocalVariable* receiver, |
2853 GrowableArray<Field*>* initialized_fields) { | 2770 GrowableArray<Field*>* initialized_fields) { |
2854 TRACE_PARSER("ParseInitializer"); | 2771 TRACE_PARSER("ParseInitializer"); |
2855 const TokenPosition field_pos = TokenPos(); | 2772 const TokenPosition field_pos = TokenPos(); |
2856 if (FLAG_assert_initializer && CurrentToken() == Token::kASSERT) { | 2773 if (FLAG_assert_initializer && CurrentToken() == Token::kASSERT) { |
2857 return ParseAssertStatement(current_function().is_const()); | 2774 return ParseAssertStatement(current_function().is_const()); |
2858 } | 2775 } |
2859 if (CurrentToken() == Token::kTHIS) { | 2776 if (CurrentToken() == Token::kTHIS) { |
2860 ConsumeToken(); | 2777 ConsumeToken(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 AstNode* initializer = CheckDuplicateFieldInit(field_pos, initialized_fields, | 2811 AstNode* initializer = CheckDuplicateFieldInit(field_pos, initialized_fields, |
2895 instance, &field, init_expr); | 2812 instance, &field, init_expr); |
2896 if (initializer == NULL) { | 2813 if (initializer == NULL) { |
2897 initializer = | 2814 initializer = |
2898 new (Z) StoreInstanceFieldNode(field_pos, instance, field, init_expr, | 2815 new (Z) StoreInstanceFieldNode(field_pos, instance, field, init_expr, |
2899 /* is_initializer = */ true); | 2816 /* is_initializer = */ true); |
2900 } | 2817 } |
2901 return initializer; | 2818 return initializer; |
2902 } | 2819 } |
2903 | 2820 |
2904 | |
2905 void Parser::CheckFieldsInitialized(const Class& cls) { | 2821 void Parser::CheckFieldsInitialized(const Class& cls) { |
2906 const Array& fields = Array::Handle(Z, cls.fields()); | 2822 const Array& fields = Array::Handle(Z, cls.fields()); |
2907 Field& field = Field::Handle(Z); | 2823 Field& field = Field::Handle(Z); |
2908 SequenceNode* initializers = current_block_->statements; | 2824 SequenceNode* initializers = current_block_->statements; |
2909 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 2825 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
2910 field ^= fields.At(field_num); | 2826 field ^= fields.At(field_num); |
2911 if (field.is_static()) { | 2827 if (field.is_static()) { |
2912 continue; | 2828 continue; |
2913 } | 2829 } |
2914 | 2830 |
(...skipping 10 matching lines...) Expand all Loading... |
2925 } | 2841 } |
2926 } | 2842 } |
2927 } | 2843 } |
2928 | 2844 |
2929 if (found) continue; | 2845 if (found) continue; |
2930 | 2846 |
2931 field.RecordStore(Object::null_object()); | 2847 field.RecordStore(Object::null_object()); |
2932 } | 2848 } |
2933 } | 2849 } |
2934 | 2850 |
2935 | |
2936 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2851 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
2937 // Only use this function if the initialized field originates | 2852 // Only use this function if the initialized field originates |
2938 // from a different class. We need to save and restore the | 2853 // from a different class. We need to save and restore the |
2939 // library and token stream (script). | 2854 // library and token stream (script). |
2940 // The current_class remains unchanged, so that type arguments | 2855 // The current_class remains unchanged, so that type arguments |
2941 // are resolved in the correct scope class. | 2856 // are resolved in the correct scope class. |
2942 ASSERT(current_class().raw() != field.Origin()); | 2857 ASSERT(current_class().raw() != field.Origin()); |
2943 const Library& saved_library = Library::Handle(Z, library().raw()); | 2858 const Library& saved_library = Library::Handle(Z, library().raw()); |
2944 const Script& saved_script = Script::Handle(Z, script().raw()); | 2859 const Script& saved_script = Script::Handle(Z, script().raw()); |
2945 const TokenPosition saved_token_pos = TokenPos(); | 2860 const TokenPosition saved_token_pos = TokenPos(); |
(...skipping 13 matching lines...) Expand all Loading... |
2959 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2874 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2960 if (init_expr->EvalConstExpr() != NULL) { | 2875 if (init_expr->EvalConstExpr() != NULL) { |
2961 init_expr = FoldConstExpr(expr_pos, init_expr); | 2876 init_expr = FoldConstExpr(expr_pos, init_expr); |
2962 } | 2877 } |
2963 } | 2878 } |
2964 set_library(saved_library); | 2879 set_library(saved_library); |
2965 SetScript(saved_script, saved_token_pos); | 2880 SetScript(saved_script, saved_token_pos); |
2966 return init_expr; | 2881 return init_expr; |
2967 } | 2882 } |
2968 | 2883 |
2969 | |
2970 void Parser::ParseInitializedInstanceFields( | 2884 void Parser::ParseInitializedInstanceFields( |
2971 const Class& cls, | 2885 const Class& cls, |
2972 LocalVariable* receiver, | 2886 LocalVariable* receiver, |
2973 GrowableArray<Field*>* initialized_fields) { | 2887 GrowableArray<Field*>* initialized_fields) { |
2974 TRACE_PARSER("ParseInitializedInstanceFields"); | 2888 TRACE_PARSER("ParseInitializedInstanceFields"); |
2975 const Array& fields = Array::Handle(Z, cls.fields()); | 2889 const Array& fields = Array::Handle(Z, cls.fields()); |
2976 Field& f = Field::Handle(Z); | 2890 Field& f = Field::Handle(Z); |
2977 const TokenPosition saved_pos = TokenPos(); | 2891 const TokenPosition saved_pos = TokenPos(); |
2978 for (int i = 0; i < fields.Length(); i++) { | 2892 for (int i = 0; i < fields.Length(); i++) { |
2979 f ^= fields.At(i); | 2893 f ^= fields.At(i); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3012 AstNode* field_init = new StoreInstanceFieldNode( | 2926 AstNode* field_init = new StoreInstanceFieldNode( |
3013 field.token_pos(), instance, field, init_expr, | 2927 field.token_pos(), instance, field, init_expr, |
3014 /* is_initializer = */ true); | 2928 /* is_initializer = */ true); |
3015 current_block_->statements->Add(field_init); | 2929 current_block_->statements->Add(field_init); |
3016 } | 2930 } |
3017 } | 2931 } |
3018 initialized_fields->Add(NULL); // End of inline initializers. | 2932 initialized_fields->Add(NULL); // End of inline initializers. |
3019 SetPosition(saved_pos); | 2933 SetPosition(saved_pos); |
3020 } | 2934 } |
3021 | 2935 |
3022 | |
3023 AstNode* Parser::CheckDuplicateFieldInit( | 2936 AstNode* Parser::CheckDuplicateFieldInit( |
3024 TokenPosition init_pos, | 2937 TokenPosition init_pos, |
3025 GrowableArray<Field*>* initialized_fields, | 2938 GrowableArray<Field*>* initialized_fields, |
3026 AstNode* instance, | 2939 AstNode* instance, |
3027 Field* field, | 2940 Field* field, |
3028 AstNode* init_value) { | 2941 AstNode* init_value) { |
3029 ASSERT(!field->is_static()); | 2942 ASSERT(!field->is_static()); |
3030 AstNode* result = NULL; | 2943 AstNode* result = NULL; |
3031 const String& field_name = String::Handle(field->name()); | 2944 const String& field_name = String::Handle(field->name()); |
3032 String& initialized_name = String::Handle(Z); | 2945 String& initialized_name = String::Handle(Z); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3115 initializer_idx++; | 3028 initializer_idx++; |
3116 if (initialized_field->raw() == field->raw()) { | 3029 if (initialized_field->raw() == field->raw()) { |
3117 ReportError(init_pos, "duplicate initializer for field %s", | 3030 ReportError(init_pos, "duplicate initializer for field %s", |
3118 String::Handle(Z, field->name()).ToCString()); | 3031 String::Handle(Z, field->name()).ToCString()); |
3119 } | 3032 } |
3120 } | 3033 } |
3121 initialized_fields->Add(field); | 3034 initialized_fields->Add(field); |
3122 return result; | 3035 return result; |
3123 } | 3036 } |
3124 | 3037 |
3125 | |
3126 void Parser::ParseInitializers(const Class& cls, | 3038 void Parser::ParseInitializers(const Class& cls, |
3127 LocalVariable* receiver, | 3039 LocalVariable* receiver, |
3128 GrowableArray<Field*>* initialized_fields) { | 3040 GrowableArray<Field*>* initialized_fields) { |
3129 TRACE_PARSER("ParseInitializers"); | 3041 TRACE_PARSER("ParseInitializers"); |
3130 bool super_init_is_last = false; | 3042 bool super_init_is_last = false; |
3131 intptr_t super_init_index = -1; | 3043 intptr_t super_init_index = -1; |
3132 StaticCallNode* super_init_call = NULL; | 3044 StaticCallNode* super_init_call = NULL; |
3133 if (CurrentToken() == Token::kCOLON) { | 3045 if (CurrentToken() == Token::kCOLON) { |
3134 do { | 3046 do { |
3135 ConsumeToken(); // Colon or comma. | 3047 ConsumeToken(); // Colon or comma. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3187 AstNode* save_temp = new (Z) StoreLocalNode(arg->token_pos(), temp, arg); | 3099 AstNode* save_temp = new (Z) StoreLocalNode(arg->token_pos(), temp, arg); |
3188 saved_args->AddNode(save_temp); | 3100 saved_args->AddNode(save_temp); |
3189 ctor_args->SetNodeAt(i, new (Z) LoadLocalNode(arg->token_pos(), temp)); | 3101 ctor_args->SetNodeAt(i, new (Z) LoadLocalNode(arg->token_pos(), temp)); |
3190 } | 3102 } |
3191 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); | 3103 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); |
3192 current_block_->statements->Add(super_init_call); | 3104 current_block_->statements->Add(super_init_call); |
3193 } | 3105 } |
3194 CheckFieldsInitialized(cls); | 3106 CheckFieldsInitialized(cls); |
3195 } | 3107 } |
3196 | 3108 |
3197 | |
3198 void Parser::ParseConstructorRedirection(const Class& cls, | 3109 void Parser::ParseConstructorRedirection(const Class& cls, |
3199 LocalVariable* receiver) { | 3110 LocalVariable* receiver) { |
3200 TRACE_PARSER("ParseConstructorRedirection"); | 3111 TRACE_PARSER("ParseConstructorRedirection"); |
3201 ExpectToken(Token::kCOLON); | 3112 ExpectToken(Token::kCOLON); |
3202 ASSERT(CurrentToken() == Token::kTHIS); | 3113 ASSERT(CurrentToken() == Token::kTHIS); |
3203 const TokenPosition call_pos = TokenPos(); | 3114 const TokenPosition call_pos = TokenPos(); |
3204 ConsumeToken(); | 3115 ConsumeToken(); |
3205 String& ctor_name = String::Handle(Z, cls.Name()); | 3116 String& ctor_name = String::Handle(Z, cls.Name()); |
3206 GrowableHandlePtrArray<const String> pieces(Z, 3); | 3117 GrowableHandlePtrArray<const String> pieces(Z, 3); |
3207 pieces.Add(ctor_name); | 3118 pieces.Add(ctor_name); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3242 arguments->length(), arguments->names(), | 3153 arguments->length(), arguments->names(), |
3243 &error_message)) { | 3154 &error_message)) { |
3244 ReportError(call_pos, "invalid arguments passed to constructor '%s': %s", | 3155 ReportError(call_pos, "invalid arguments passed to constructor '%s': %s", |
3245 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString(), | 3156 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString(), |
3246 error_message.ToCString()); | 3157 error_message.ToCString()); |
3247 } | 3158 } |
3248 current_block_->statements->Add( | 3159 current_block_->statements->Add( |
3249 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 3160 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
3250 } | 3161 } |
3251 | 3162 |
3252 | |
3253 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 3163 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
3254 ASSERT(func.IsGenerativeConstructor()); | 3164 ASSERT(func.IsGenerativeConstructor()); |
3255 ASSERT(func.Owner() == current_class().raw()); | 3165 ASSERT(func.Owner() == current_class().raw()); |
3256 const TokenPosition ctor_pos = TokenPos(); | 3166 const TokenPosition ctor_pos = TokenPos(); |
3257 OpenFunctionBlock(func); | 3167 OpenFunctionBlock(func); |
3258 | 3168 |
3259 LocalVariable* receiver = | 3169 LocalVariable* receiver = |
3260 new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 3170 new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
3261 Symbols::This(), *ReceiverType(current_class())); | 3171 Symbols::This(), *ReceiverType(current_class())); |
3262 current_block_->scope->InsertParameterAt(0, receiver); | 3172 current_block_->scope->InsertParameterAt(0, receiver); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3318 current_block_->statements->Add(super_call); | 3228 current_block_->statements->Add(super_call); |
3319 } | 3229 } |
3320 CheckFieldsInitialized(current_class()); | 3230 CheckFieldsInitialized(current_class()); |
3321 | 3231 |
3322 // Empty constructor body. | 3232 // Empty constructor body. |
3323 current_block_->statements->Add(new ReturnNode(ST(ctor_pos))); | 3233 current_block_->statements->Add(new ReturnNode(ST(ctor_pos))); |
3324 SequenceNode* statements = CloseBlock(); | 3234 SequenceNode* statements = CloseBlock(); |
3325 return statements; | 3235 return statements; |
3326 } | 3236 } |
3327 | 3237 |
3328 | |
3329 // Returns a zone allocated string. | 3238 // Returns a zone allocated string. |
3330 static char* DumpPendingFunctions( | 3239 static char* DumpPendingFunctions( |
3331 Zone* zone, | 3240 Zone* zone, |
3332 const GrowableObjectArray& pending_functions) { | 3241 const GrowableObjectArray& pending_functions) { |
3333 ASSERT(zone != NULL); | 3242 ASSERT(zone != NULL); |
3334 char* result = OS::SCreate(zone, "Pending Functions:\n"); | 3243 char* result = OS::SCreate(zone, "Pending Functions:\n"); |
3335 for (intptr_t i = 0; i < pending_functions.Length(); i++) { | 3244 for (intptr_t i = 0; i < pending_functions.Length(); i++) { |
3336 const Function& func = | 3245 const Function& func = |
3337 Function::Handle(zone, Function::RawCast(pending_functions.At(i))); | 3246 Function::Handle(zone, Function::RawCast(pending_functions.At(i))); |
3338 const String& fname = String::Handle(zone, func.UserVisibleName()); | 3247 const String& fname = String::Handle(zone, func.UserVisibleName()); |
3339 result = OS::SCreate(zone, "%s%" Pd ": %s\n", result, i, fname.ToCString()); | 3248 result = OS::SCreate(zone, "%s%" Pd ": %s\n", result, i, fname.ToCString()); |
3340 } | 3249 } |
3341 return result; | 3250 return result; |
3342 } | 3251 } |
3343 | 3252 |
3344 | |
3345 void Parser::CheckRecursiveInvocation() { | 3253 void Parser::CheckRecursiveInvocation() { |
3346 const GrowableObjectArray& pending_functions = | 3254 const GrowableObjectArray& pending_functions = |
3347 GrowableObjectArray::Handle(Z, T->pending_functions()); | 3255 GrowableObjectArray::Handle(Z, T->pending_functions()); |
3348 ASSERT(!pending_functions.IsNull()); | 3256 ASSERT(!pending_functions.IsNull()); |
3349 for (int i = 0; i < pending_functions.Length(); i++) { | 3257 for (int i = 0; i < pending_functions.Length(); i++) { |
3350 if (pending_functions.At(i) == current_function().raw()) { | 3258 if (pending_functions.At(i) == current_function().raw()) { |
3351 const String& fname = | 3259 const String& fname = |
3352 String::Handle(Z, current_function().UserVisibleName()); | 3260 String::Handle(Z, current_function().UserVisibleName()); |
3353 if (FLAG_trace_service) { | 3261 if (FLAG_trace_service) { |
3354 const char* pending_function_dump = | 3262 const char* pending_function_dump = |
3355 DumpPendingFunctions(Z, pending_functions); | 3263 DumpPendingFunctions(Z, pending_functions); |
3356 ASSERT(pending_function_dump != NULL); | 3264 ASSERT(pending_function_dump != NULL); |
3357 ReportError("circular dependency for function %s\n%s", | 3265 ReportError("circular dependency for function %s\n%s", |
3358 fname.ToCString(), pending_function_dump); | 3266 fname.ToCString(), pending_function_dump); |
3359 } else { | 3267 } else { |
3360 ReportError("circular dependency for function %s", fname.ToCString()); | 3268 ReportError("circular dependency for function %s", fname.ToCString()); |
3361 } | 3269 } |
3362 } | 3270 } |
3363 } | 3271 } |
3364 ASSERT(!unregister_pending_function_); | 3272 ASSERT(!unregister_pending_function_); |
3365 pending_functions.Add(current_function(), Heap::kOld); | 3273 pending_functions.Add(current_function(), Heap::kOld); |
3366 unregister_pending_function_ = true; | 3274 unregister_pending_function_ = true; |
3367 } | 3275 } |
3368 | 3276 |
3369 | |
3370 // Parser is at the opening parenthesis of the formal parameter declaration | 3277 // Parser is at the opening parenthesis of the formal parameter declaration |
3371 // of function. Parse the formal parameters, initializers and code. | 3278 // of function. Parse the formal parameters, initializers and code. |
3372 SequenceNode* Parser::ParseConstructor(const Function& func) { | 3279 SequenceNode* Parser::ParseConstructor(const Function& func) { |
3373 TRACE_PARSER("ParseConstructor"); | 3280 TRACE_PARSER("ParseConstructor"); |
3374 ASSERT(func.IsGenerativeConstructor()); | 3281 ASSERT(func.IsGenerativeConstructor()); |
3375 ASSERT(!func.IsFactory()); | 3282 ASSERT(!func.IsFactory()); |
3376 ASSERT(!func.is_static()); | 3283 ASSERT(!func.is_static()); |
3377 ASSERT(!func.IsLocalFunction()); | 3284 ASSERT(!func.IsLocalFunction()); |
3378 const Class& cls = Class::Handle(Z, func.Owner()); | 3285 const Class& cls = Class::Handle(Z, func.Owner()); |
3379 ASSERT(!cls.IsNull()); | 3286 ASSERT(!cls.IsNull()); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3534 | 3441 |
3535 SequenceNode* ctor_block = CloseBlock(); | 3442 SequenceNode* ctor_block = CloseBlock(); |
3536 if (ctor_block->length() > 0) { | 3443 if (ctor_block->length() > 0) { |
3537 current_block_->statements->Add(ctor_block); | 3444 current_block_->statements->Add(ctor_block); |
3538 } | 3445 } |
3539 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 3446 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
3540 SequenceNode* statements = CloseBlock(); | 3447 SequenceNode* statements = CloseBlock(); |
3541 return statements; | 3448 return statements; |
3542 } | 3449 } |
3543 | 3450 |
3544 | |
3545 // Parser is at the opening parenthesis of the formal parameter | 3451 // Parser is at the opening parenthesis of the formal parameter |
3546 // declaration of the function or constructor. | 3452 // declaration of the function or constructor. |
3547 // Parse the formal parameters and code. | 3453 // Parse the formal parameters and code. |
3548 SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) { | 3454 SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) { |
3549 TRACE_PARSER("ParseFunc"); | 3455 TRACE_PARSER("ParseFunc"); |
3550 ASSERT(innermost_function().raw() == func.raw()); | 3456 ASSERT(innermost_function().raw() == func.raw()); |
3551 | 3457 |
3552 // Save current try index. Try index starts at zero for each function. | 3458 // Save current try index. Try index starts at zero for each function. |
3553 intptr_t saved_try_index = last_used_try_index_; | 3459 intptr_t saved_try_index = last_used_try_index_; |
3554 last_used_try_index_ = 0; | 3460 last_used_try_index_ = 0; |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3838 } else if (func.IsAsyncGenClosure()) { | 3744 } else if (func.IsAsyncGenClosure()) { |
3839 body = CloseAsyncGeneratorClosure(body); | 3745 body = CloseAsyncGeneratorClosure(body); |
3840 } | 3746 } |
3841 EnsureHasReturnStatement(body, end_token_pos); | 3747 EnsureHasReturnStatement(body, end_token_pos); |
3842 current_block_->statements->Add(body); | 3748 current_block_->statements->Add(body); |
3843 last_used_try_index_ = saved_try_index; | 3749 last_used_try_index_ = saved_try_index; |
3844 async_temp_scope_ = saved_async_temp_scope; | 3750 async_temp_scope_ = saved_async_temp_scope; |
3845 return CloseBlock(); | 3751 return CloseBlock(); |
3846 } | 3752 } |
3847 | 3753 |
3848 | |
3849 void Parser::AddEqualityNullCheck() { | 3754 void Parser::AddEqualityNullCheck() { |
3850 AstNode* argument = new LoadLocalNode( | 3755 AstNode* argument = new LoadLocalNode( |
3851 TokenPosition::kNoSource, current_block_->scope->parent()->VariableAt(1)); | 3756 TokenPosition::kNoSource, current_block_->scope->parent()->VariableAt(1)); |
3852 LiteralNode* null_operand = | 3757 LiteralNode* null_operand = |
3853 new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z)); | 3758 new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z)); |
3854 ComparisonNode* check_arg = new ComparisonNode( | 3759 ComparisonNode* check_arg = new ComparisonNode( |
3855 TokenPosition::kNoSource, Token::kEQ_STRICT, argument, null_operand); | 3760 TokenPosition::kNoSource, Token::kEQ_STRICT, argument, null_operand); |
3856 ComparisonNode* result = | 3761 ComparisonNode* result = |
3857 new ComparisonNode(TokenPosition::kNoSource, Token::kEQ_STRICT, | 3762 new ComparisonNode(TokenPosition::kNoSource, Token::kEQ_STRICT, |
3858 LoadReceiver(TokenPosition::kNoSource), null_operand); | 3763 LoadReceiver(TokenPosition::kNoSource), null_operand); |
3859 SequenceNode* arg_is_null = | 3764 SequenceNode* arg_is_null = |
3860 new SequenceNode(TokenPosition::kNoSource, current_block_->scope); | 3765 new SequenceNode(TokenPosition::kNoSource, current_block_->scope); |
3861 arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result)); | 3766 arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result)); |
3862 IfNode* if_arg_null = | 3767 IfNode* if_arg_null = |
3863 new IfNode(TokenPosition::kNoSource, check_arg, arg_is_null, NULL); | 3768 new IfNode(TokenPosition::kNoSource, check_arg, arg_is_null, NULL); |
3864 current_block_->statements->Add(if_arg_null); | 3769 current_block_->statements->Add(if_arg_null); |
3865 } | 3770 } |
3866 | 3771 |
3867 | |
3868 void Parser::SkipIf(Token::Kind token) { | 3772 void Parser::SkipIf(Token::Kind token) { |
3869 if (CurrentToken() == token) { | 3773 if (CurrentToken() == token) { |
3870 ConsumeToken(); | 3774 ConsumeToken(); |
3871 } | 3775 } |
3872 } | 3776 } |
3873 | 3777 |
3874 | |
3875 void Parser::SkipInitializers() { | 3778 void Parser::SkipInitializers() { |
3876 ASSERT(CurrentToken() == Token::kCOLON); | 3779 ASSERT(CurrentToken() == Token::kCOLON); |
3877 do { | 3780 do { |
3878 ConsumeToken(); // Colon or comma. | 3781 ConsumeToken(); // Colon or comma. |
3879 if (CurrentToken() == Token::kSUPER) { | 3782 if (CurrentToken() == Token::kSUPER) { |
3880 ConsumeToken(); | 3783 ConsumeToken(); |
3881 if (CurrentToken() == Token::kPERIOD) { | 3784 if (CurrentToken() == Token::kPERIOD) { |
3882 ConsumeToken(); | 3785 ConsumeToken(); |
3883 ExpectIdentifier("identifier expected"); | 3786 ExpectIdentifier("identifier expected"); |
3884 } | 3787 } |
3885 CheckToken(Token::kLPAREN); | 3788 CheckToken(Token::kLPAREN); |
3886 SkipToMatchingParenthesis(); | 3789 SkipToMatchingParenthesis(); |
3887 } else if (FLAG_assert_initializer && (CurrentToken() == Token::kASSERT)) { | 3790 } else if (FLAG_assert_initializer && (CurrentToken() == Token::kASSERT)) { |
3888 ConsumeToken(); | 3791 ConsumeToken(); |
3889 CheckToken(Token::kLPAREN); | 3792 CheckToken(Token::kLPAREN); |
3890 SkipToMatchingParenthesis(); | 3793 SkipToMatchingParenthesis(); |
3891 } else { | 3794 } else { |
3892 SkipIf(Token::kTHIS); | 3795 SkipIf(Token::kTHIS); |
3893 SkipIf(Token::kPERIOD); | 3796 SkipIf(Token::kPERIOD); |
3894 ExpectIdentifier("identifier expected"); | 3797 ExpectIdentifier("identifier expected"); |
3895 ExpectToken(Token::kASSIGN); | 3798 ExpectToken(Token::kASSIGN); |
3896 SetAllowFunctionLiterals(false); | 3799 SetAllowFunctionLiterals(false); |
3897 SkipExpr(); | 3800 SkipExpr(); |
3898 SetAllowFunctionLiterals(true); | 3801 SetAllowFunctionLiterals(true); |
3899 } | 3802 } |
3900 } while (CurrentToken() == Token::kCOMMA); | 3803 } while (CurrentToken() == Token::kCOMMA); |
3901 } | 3804 } |
3902 | 3805 |
3903 | |
3904 // If the current identifier is a library prefix followed by a period, | 3806 // If the current identifier is a library prefix followed by a period, |
3905 // consume the identifier and period, and return the resolved library | 3807 // consume the identifier and period, and return the resolved library |
3906 // prefix. | 3808 // prefix. |
3907 RawLibraryPrefix* Parser::ParsePrefix() { | 3809 RawLibraryPrefix* Parser::ParsePrefix() { |
3908 ASSERT(IsIdentifier()); | 3810 ASSERT(IsIdentifier()); |
3909 // A library prefix can never stand by itself. It must be followed by | 3811 // A library prefix can never stand by itself. It must be followed by |
3910 // a period or a hash mark (for closurization). | 3812 // a period or a hash mark (for closurization). |
3911 Token::Kind next_token = LookaheadToken(1); | 3813 Token::Kind next_token = LookaheadToken(1); |
3912 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) { | 3814 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) { |
3913 return LibraryPrefix::null(); | 3815 return LibraryPrefix::null(); |
(...skipping 26 matching lines...) Expand all Loading... |
3940 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { | 3842 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { |
3941 return LibraryPrefix::null(); | 3843 return LibraryPrefix::null(); |
3942 } | 3844 } |
3943 | 3845 |
3944 // We have a name that is not shadowed, followed by a period or #. | 3846 // We have a name that is not shadowed, followed by a period or #. |
3945 // Consume the identifier, let the caller consume the . or #. | 3847 // Consume the identifier, let the caller consume the . or #. |
3946 ConsumeToken(); | 3848 ConsumeToken(); |
3947 return prefix.raw(); | 3849 return prefix.raw(); |
3948 } | 3850 } |
3949 | 3851 |
3950 | |
3951 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3852 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
3952 TRACE_PARSER("ParseMethodOrConstructor"); | 3853 TRACE_PARSER("ParseMethodOrConstructor"); |
3953 // We are at the beginning of the formal parameters list. | 3854 // We are at the beginning of the formal parameters list. |
3954 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT || | 3855 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT || |
3955 method->IsGetter()); | 3856 method->IsGetter()); |
3956 ASSERT(method->type != NULL); // May still be unresolved. | 3857 ASSERT(method->type != NULL); // May still be unresolved. |
3957 ASSERT(current_member_ == method); | 3858 ASSERT(current_member_ == method); |
3958 | 3859 |
3959 if (method->has_covariant) { | 3860 if (method->has_covariant) { |
3960 ReportError(method->name_pos, | 3861 ReportError(method->name_pos, |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4302 } | 4203 } |
4303 | 4204 |
4304 ASSERT(is_top_level_); | 4205 ASSERT(is_top_level_); |
4305 AddFormalParamsToFunction(&method->params, func); | 4206 AddFormalParamsToFunction(&method->params, func); |
4306 ASSERT(innermost_function().raw() == func.raw()); | 4207 ASSERT(innermost_function().raw() == func.raw()); |
4307 innermost_function_ = Function::null(); | 4208 innermost_function_ = Function::null(); |
4308 ResolveSignature(func); | 4209 ResolveSignature(func); |
4309 members->AddFunction(func); | 4210 members->AddFunction(func); |
4310 } | 4211 } |
4311 | 4212 |
4312 | |
4313 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 4213 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
4314 TRACE_PARSER("ParseFieldDefinition"); | 4214 TRACE_PARSER("ParseFieldDefinition"); |
4315 // The parser has read the first field name and is now at the token | 4215 // The parser has read the first field name and is now at the token |
4316 // after the field name. | 4216 // after the field name. |
4317 ASSERT(CurrentToken() == Token::kSEMICOLON || | 4217 ASSERT(CurrentToken() == Token::kSEMICOLON || |
4318 CurrentToken() == Token::kCOMMA || CurrentToken() == Token::kASSIGN); | 4218 CurrentToken() == Token::kCOMMA || CurrentToken() == Token::kASSIGN); |
4319 ASSERT(field->type != NULL); | 4219 ASSERT(field->type != NULL); |
4320 ASSERT(field->name_pos.IsReal()); | 4220 ASSERT(field->name_pos.IsReal()); |
4321 ASSERT(current_member_ == field); | 4221 ASSERT(current_member_ == field); |
4322 // All const fields are also final. | 4222 // All const fields are also final. |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4475 if (CurrentToken() != Token::kCOMMA) { | 4375 if (CurrentToken() != Token::kCOMMA) { |
4476 break; | 4376 break; |
4477 } | 4377 } |
4478 ConsumeToken(); | 4378 ConsumeToken(); |
4479 field->name_pos = this->TokenPos(); | 4379 field->name_pos = this->TokenPos(); |
4480 field->name = ExpectIdentifier("field name expected"); | 4380 field->name = ExpectIdentifier("field name expected"); |
4481 } | 4381 } |
4482 ExpectSemicolon(); | 4382 ExpectSemicolon(); |
4483 } | 4383 } |
4484 | 4384 |
4485 | |
4486 void Parser::CheckOperatorArity(const MemberDesc& member) { | 4385 void Parser::CheckOperatorArity(const MemberDesc& member) { |
4487 intptr_t expected_num_parameters; // Includes receiver. | 4386 intptr_t expected_num_parameters; // Includes receiver. |
4488 Token::Kind op = member.operator_token; | 4387 Token::Kind op = member.operator_token; |
4489 if (op == Token::kASSIGN_INDEX) { | 4388 if (op == Token::kASSIGN_INDEX) { |
4490 expected_num_parameters = 3; | 4389 expected_num_parameters = 3; |
4491 } else if ((op == Token::kBIT_NOT) || (op == Token::kNEGATE)) { | 4390 } else if ((op == Token::kBIT_NOT) || (op == Token::kNEGATE)) { |
4492 expected_num_parameters = 1; | 4391 expected_num_parameters = 1; |
4493 } else { | 4392 } else { |
4494 expected_num_parameters = 2; | 4393 expected_num_parameters = 2; |
4495 } | 4394 } |
4496 if ((member.params.num_optional_parameters > 0) || | 4395 if ((member.params.num_optional_parameters > 0) || |
4497 member.params.has_optional_positional_parameters || | 4396 member.params.has_optional_positional_parameters || |
4498 member.params.has_optional_named_parameters || | 4397 member.params.has_optional_named_parameters || |
4499 (member.params.num_fixed_parameters != expected_num_parameters)) { | 4398 (member.params.num_fixed_parameters != expected_num_parameters)) { |
4500 // Subtract receiver when reporting number of expected arguments. | 4399 // Subtract receiver when reporting number of expected arguments. |
4501 ReportError(member.name_pos, "operator %s expects %" Pd " argument(s)", | 4400 ReportError(member.name_pos, "operator %s expects %" Pd " argument(s)", |
4502 member.name->ToCString(), (expected_num_parameters - 1)); | 4401 member.name->ToCString(), (expected_num_parameters - 1)); |
4503 } | 4402 } |
4504 } | 4403 } |
4505 | 4404 |
4506 | |
4507 void Parser::CheckMemberNameConflict(ClassDesc* members, MemberDesc* member) { | 4405 void Parser::CheckMemberNameConflict(ClassDesc* members, MemberDesc* member) { |
4508 const String& name = *member->DictName(); | 4406 const String& name = *member->DictName(); |
4509 if (name.Equals(members->class_name())) { | 4407 if (name.Equals(members->class_name())) { |
4510 ReportError(member->name_pos, "%s '%s' conflicts with class name", | 4408 ReportError(member->name_pos, "%s '%s' conflicts with class name", |
4511 member->ToCString(), name.ToCString()); | 4409 member->ToCString(), name.ToCString()); |
4512 } | 4410 } |
4513 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { | 4411 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { |
4514 ReportError(member->name_pos, "%s '%s' conflicts with type parameter", | 4412 ReportError(member->name_pos, "%s '%s' conflicts with type parameter", |
4515 member->ToCString(), name.ToCString()); | 4413 member->ToCString(), name.ToCString()); |
4516 } | 4414 } |
4517 for (int i = 0; i < members->members().length(); i++) { | 4415 for (int i = 0; i < members->members().length(); i++) { |
4518 MemberDesc* existing_member = &members->members()[i]; | 4416 MemberDesc* existing_member = &members->members()[i]; |
4519 if (name.Equals(*existing_member->DictName())) { | 4417 if (name.Equals(*existing_member->DictName())) { |
4520 ReportError( | 4418 ReportError( |
4521 member->name_pos, "%s '%s' conflicts with previously declared %s", | 4419 member->name_pos, "%s '%s' conflicts with previously declared %s", |
4522 member->ToCString(), name.ToCString(), existing_member->ToCString()); | 4420 member->ToCString(), name.ToCString(), existing_member->ToCString()); |
4523 } | 4421 } |
4524 } | 4422 } |
4525 } | 4423 } |
4526 | 4424 |
4527 | |
4528 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 4425 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
4529 TokenPosition metadata_pos) { | 4426 TokenPosition metadata_pos) { |
4530 TRACE_PARSER("ParseClassMemberDefinition"); | 4427 TRACE_PARSER("ParseClassMemberDefinition"); |
4531 MemberDesc member; | 4428 MemberDesc member; |
4532 current_member_ = &member; | 4429 current_member_ = &member; |
4533 member.metadata_pos = metadata_pos; | 4430 member.metadata_pos = metadata_pos; |
4534 member.decl_begin_pos = TokenPos(); | 4431 member.decl_begin_pos = TokenPos(); |
4535 if ((CurrentToken() == Token::kEXTERNAL) && | 4432 if ((CurrentToken() == Token::kEXTERNAL) && |
4536 (LookaheadToken(1) != Token::kLPAREN)) { | 4433 (LookaheadToken(1) != Token::kLPAREN)) { |
4537 ConsumeToken(); | 4434 ConsumeToken(); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4733 } | 4630 } |
4734 ParseFieldDefinition(members, &member); | 4631 ParseFieldDefinition(members, &member); |
4735 } else { | 4632 } else { |
4736 UnexpectedToken(); | 4633 UnexpectedToken(); |
4737 } | 4634 } |
4738 current_member_ = NULL; | 4635 current_member_ = NULL; |
4739 CheckMemberNameConflict(members, &member); | 4636 CheckMemberNameConflict(members, &member); |
4740 members->AddMember(member); | 4637 members->AddMember(member); |
4741 } | 4638 } |
4742 | 4639 |
4743 | |
4744 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, | 4640 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
4745 const Object& tl_owner, | 4641 const Object& tl_owner, |
4746 TokenPosition metadata_pos) { | 4642 TokenPosition metadata_pos) { |
4747 TRACE_PARSER("ParseEnumDeclaration"); | 4643 TRACE_PARSER("ParseEnumDeclaration"); |
4748 const TokenPosition declaration_pos = | 4644 const TokenPosition declaration_pos = |
4749 (metadata_pos.IsReal()) ? metadata_pos : TokenPos(); | 4645 (metadata_pos.IsReal()) ? metadata_pos : TokenPos(); |
4750 ConsumeToken(); | 4646 ConsumeToken(); |
4751 const TokenPosition name_pos = TokenPos(); | 4647 const TokenPosition name_pos = TokenPos(); |
4752 String* enum_name = | 4648 String* enum_name = |
4753 ExpectUserDefinedTypeIdentifier("enum type name expected"); | 4649 ExpectUserDefinedTypeIdentifier("enum type name expected"); |
(...skipping 28 matching lines...) Expand all Loading... |
4782 library_.AddClass(cls); | 4678 library_.AddClass(cls); |
4783 cls.set_is_synthesized_class(); | 4679 cls.set_is_synthesized_class(); |
4784 cls.set_is_enum_class(); | 4680 cls.set_is_enum_class(); |
4785 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { | 4681 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { |
4786 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4682 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
4787 } | 4683 } |
4788 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); | 4684 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); |
4789 pending_classes.Add(cls, Heap::kOld); | 4685 pending_classes.Add(cls, Heap::kOld); |
4790 } | 4686 } |
4791 | 4687 |
4792 | |
4793 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4688 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
4794 const Object& tl_owner, | 4689 const Object& tl_owner, |
4795 TokenPosition metadata_pos) { | 4690 TokenPosition metadata_pos) { |
4796 TRACE_PARSER("ParseClassDeclaration"); | 4691 TRACE_PARSER("ParseClassDeclaration"); |
4797 bool is_patch = false; | 4692 bool is_patch = false; |
4798 bool is_abstract = false; | 4693 bool is_abstract = false; |
4799 TokenPosition declaration_pos = | 4694 TokenPosition declaration_pos = |
4800 metadata_pos.IsReal() ? metadata_pos : TokenPos(); | 4695 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
4801 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 4696 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
4802 is_patch = true; | 4697 is_patch = true; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4968 | 4863 |
4969 if (is_mixin_declaration) { | 4864 if (is_mixin_declaration) { |
4970 ExpectSemicolon(); | 4865 ExpectSemicolon(); |
4971 } else { | 4866 } else { |
4972 CheckToken(Token::kLBRACE); | 4867 CheckToken(Token::kLBRACE); |
4973 SkipBlock(); | 4868 SkipBlock(); |
4974 ExpectToken(Token::kRBRACE); | 4869 ExpectToken(Token::kRBRACE); |
4975 } | 4870 } |
4976 } | 4871 } |
4977 | 4872 |
4978 | |
4979 void Parser::ParseClassDefinition(const Class& cls) { | 4873 void Parser::ParseClassDefinition(const Class& cls) { |
4980 TRACE_PARSER("ParseClassDefinition"); | 4874 TRACE_PARSER("ParseClassDefinition"); |
4981 INC_STAT(thread(), num_classes_parsed, 1); | 4875 INC_STAT(thread(), num_classes_parsed, 1); |
4982 set_current_class(cls); | 4876 set_current_class(cls); |
4983 is_top_level_ = true; | 4877 is_top_level_ = true; |
4984 String& class_name = String::Handle(Z, cls.Name()); | 4878 String& class_name = String::Handle(Z, cls.Name()); |
4985 SkipMetadata(); | 4879 SkipMetadata(); |
4986 if (CurrentToken() == Token::kABSTRACT) { | 4880 if (CurrentToken() == Token::kABSTRACT) { |
4987 ConsumeToken(); | 4881 ConsumeToken(); |
4988 } | 4882 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5036 Report::LongJumpF(error, script_, class_pos, | 4930 Report::LongJumpF(error, script_, class_pos, |
5037 "patch validation failed, not applying patch.\n"); | 4931 "patch validation failed, not applying patch.\n"); |
5038 } | 4932 } |
5039 } | 4933 } |
5040 if (!orig_class.ApplyPatch(cls, &error)) { | 4934 if (!orig_class.ApplyPatch(cls, &error)) { |
5041 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4935 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
5042 } | 4936 } |
5043 } | 4937 } |
5044 } | 4938 } |
5045 | 4939 |
5046 | |
5047 void Parser::ParseEnumDefinition(const Class& cls) { | 4940 void Parser::ParseEnumDefinition(const Class& cls) { |
5048 TRACE_PARSER("ParseEnumDefinition"); | 4941 TRACE_PARSER("ParseEnumDefinition"); |
5049 INC_STAT(thread(), num_classes_parsed, 1); | 4942 INC_STAT(thread(), num_classes_parsed, 1); |
5050 set_current_class(cls); | 4943 set_current_class(cls); |
5051 const Class& helper_class = | 4944 const Class& helper_class = |
5052 Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper())); | 4945 Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper())); |
5053 ASSERT(!helper_class.IsNull()); | 4946 ASSERT(!helper_class.IsNull()); |
5054 | 4947 |
5055 SkipMetadata(); | 4948 SkipMetadata(); |
5056 ExpectToken(Token::kENUM); | 4949 ExpectToken(Token::kENUM); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5227 Z, helper_class.LookupDynamicFunctionAllowPrivate(Symbols::hashCode())); | 5120 Z, helper_class.LookupDynamicFunctionAllowPrivate(Symbols::hashCode())); |
5228 ASSERT(!hash_code_func.IsNull()); | 5121 ASSERT(!hash_code_func.IsNull()); |
5229 hash_code_func = hash_code_func.Clone(cls); | 5122 hash_code_func = hash_code_func.Clone(cls); |
5230 enum_members.AddFunction(hash_code_func); | 5123 enum_members.AddFunction(hash_code_func); |
5231 | 5124 |
5232 cls.AddFields(enum_members.fields()); | 5125 cls.AddFields(enum_members.fields()); |
5233 const Array& functions = Array::Handle(Z, enum_members.MakeFunctionsArray()); | 5126 const Array& functions = Array::Handle(Z, enum_members.MakeFunctionsArray()); |
5234 cls.SetFunctions(functions); | 5127 cls.SetFunctions(functions); |
5235 } | 5128 } |
5236 | 5129 |
5237 | |
5238 // Add an implicit constructor to the given class. | 5130 // Add an implicit constructor to the given class. |
5239 void Parser::AddImplicitConstructor(const Class& cls) { | 5131 void Parser::AddImplicitConstructor(const Class& cls) { |
5240 // The implicit constructor is unnamed, has no explicit parameter. | 5132 // The implicit constructor is unnamed, has no explicit parameter. |
5241 String& ctor_name = String::ZoneHandle(Z, cls.Name()); | 5133 String& ctor_name = String::ZoneHandle(Z, cls.Name()); |
5242 ctor_name = Symbols::FromDot(T, ctor_name); | 5134 ctor_name = Symbols::FromDot(T, ctor_name); |
5243 // To indicate that this is an implicit constructor, we set the | 5135 // To indicate that this is an implicit constructor, we set the |
5244 // token position and end token position of the function | 5136 // token position and end token position of the function |
5245 // to the token position of the class. | 5137 // to the token position of the class. |
5246 Function& ctor = Function::Handle( | 5138 Function& ctor = Function::Handle( |
5247 Z, Function::New(ctor_name, RawFunction::kConstructor, | 5139 Z, Function::New(ctor_name, RawFunction::kConstructor, |
(...skipping 15 matching lines...) Expand all Loading... |
5263 | 5155 |
5264 AddFormalParamsToFunction(¶ms, ctor); | 5156 AddFormalParamsToFunction(¶ms, ctor); |
5265 ctor.set_result_type(Object::dynamic_type()); | 5157 ctor.set_result_type(Object::dynamic_type()); |
5266 ResolveSignature(ctor); | 5158 ResolveSignature(ctor); |
5267 // The body of the constructor cannot modify the type of the constructed | 5159 // The body of the constructor cannot modify the type of the constructed |
5268 // instance, which is passed in as the receiver. | 5160 // instance, which is passed in as the receiver. |
5269 ctor.set_result_type(*receiver_type); | 5161 ctor.set_result_type(*receiver_type); |
5270 cls.AddFunction(ctor); | 5162 cls.AddFunction(ctor); |
5271 } | 5163 } |
5272 | 5164 |
5273 | |
5274 void Parser::CheckFinalInitializationConflicts(const ClassDesc* class_desc, | 5165 void Parser::CheckFinalInitializationConflicts(const ClassDesc* class_desc, |
5275 const MemberDesc* member) { | 5166 const MemberDesc* member) { |
5276 const ParamList* params = &member->params; | 5167 const ParamList* params = &member->params; |
5277 if (!params->has_field_initializer) { | 5168 if (!params->has_field_initializer) { |
5278 return; | 5169 return; |
5279 } | 5170 } |
5280 | 5171 |
5281 const ZoneGrowableArray<ParamDesc>& parameters = *params->parameters; | 5172 const ZoneGrowableArray<ParamDesc>& parameters = *params->parameters; |
5282 const GrowableArray<const Field*>& fields = class_desc->fields(); | 5173 const GrowableArray<const Field*>& fields = class_desc->fields(); |
5283 String& field_name = String::Handle(Z); | 5174 String& field_name = String::Handle(Z); |
(...skipping 14 matching lines...) Expand all Loading... |
5298 field_name ^= current_field->name(); | 5189 field_name ^= current_field->name(); |
5299 if (param_name.Equals(field_name)) { | 5190 if (param_name.Equals(field_name)) { |
5300 ReportError(current_param.name_pos, | 5191 ReportError(current_param.name_pos, |
5301 "final field '%s' is already initialized.", | 5192 "final field '%s' is already initialized.", |
5302 param_name.ToCString()); | 5193 param_name.ToCString()); |
5303 } | 5194 } |
5304 } | 5195 } |
5305 } | 5196 } |
5306 } | 5197 } |
5307 | 5198 |
5308 | |
5309 // Check for cycles in constructor redirection. | 5199 // Check for cycles in constructor redirection. |
5310 void Parser::CheckConstructors(ClassDesc* class_desc) { | 5200 void Parser::CheckConstructors(ClassDesc* class_desc) { |
5311 // Check for cycles in constructor redirection. | 5201 // Check for cycles in constructor redirection. |
5312 const GrowableArray<MemberDesc>& members = class_desc->members(); | 5202 const GrowableArray<MemberDesc>& members = class_desc->members(); |
5313 for (int i = 0; i < members.length(); i++) { | 5203 for (int i = 0; i < members.length(); i++) { |
5314 MemberDesc* member = &members[i]; | 5204 MemberDesc* member = &members[i]; |
5315 if (member->IsConstructor()) { | 5205 if (member->IsConstructor()) { |
5316 // Check that our constructors don't try and reinitialize an initialized | 5206 // Check that our constructors don't try and reinitialize an initialized |
5317 // final variable. | 5207 // final variable. |
5318 CheckFinalInitializationConflicts(class_desc, member); | 5208 CheckFinalInitializationConflicts(class_desc, member); |
(...skipping 15 matching lines...) Expand all Loading... |
5334 // the next redirection. If we can't find the constructor to | 5224 // the next redirection. If we can't find the constructor to |
5335 // which the current one redirects, we ignore the unresolved | 5225 // which the current one redirects, we ignore the unresolved |
5336 // reference. We'll catch it later when the constructor gets | 5226 // reference. We'll catch it later when the constructor gets |
5337 // compiled. | 5227 // compiled. |
5338 ctors.Add(member); | 5228 ctors.Add(member); |
5339 member = class_desc->LookupMember(*member->redirect_name); | 5229 member = class_desc->LookupMember(*member->redirect_name); |
5340 } | 5230 } |
5341 } | 5231 } |
5342 } | 5232 } |
5343 | 5233 |
5344 | |
5345 void Parser::ParseMixinAppAlias(const GrowableObjectArray& pending_classes, | 5234 void Parser::ParseMixinAppAlias(const GrowableObjectArray& pending_classes, |
5346 const Object& tl_owner, | 5235 const Object& tl_owner, |
5347 TokenPosition metadata_pos) { | 5236 TokenPosition metadata_pos) { |
5348 TRACE_PARSER("ParseMixinAppAlias"); | 5237 TRACE_PARSER("ParseMixinAppAlias"); |
5349 const TokenPosition classname_pos = TokenPos(); | 5238 const TokenPosition classname_pos = TokenPos(); |
5350 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 5239 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
5351 if (FLAG_trace_parser) { | 5240 if (FLAG_trace_parser) { |
5352 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 5241 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
5353 class_name.ToCString()); | 5242 class_name.ToCString()); |
5354 } | 5243 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5392 if (CurrentToken() == Token::kIMPLEMENTS) { | 5281 if (CurrentToken() == Token::kIMPLEMENTS) { |
5393 ParseInterfaceList(mixin_application); | 5282 ParseInterfaceList(mixin_application); |
5394 } | 5283 } |
5395 ExpectSemicolon(); | 5284 ExpectSemicolon(); |
5396 pending_classes.Add(mixin_application, Heap::kOld); | 5285 pending_classes.Add(mixin_application, Heap::kOld); |
5397 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5286 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5398 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); | 5287 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); |
5399 } | 5288 } |
5400 } | 5289 } |
5401 | 5290 |
5402 | |
5403 // Look ahead to detect if we are seeing ident [ TypeParameters ] ("(" | "="). | 5291 // Look ahead to detect if we are seeing ident [ TypeParameters ] ("(" | "="). |
5404 // We need this lookahead to distinguish between the optional return type | 5292 // We need this lookahead to distinguish between the optional return type |
5405 // and the alias name of a function type alias. | 5293 // and the alias name of a function type alias. |
5406 // Token position remains unchanged. | 5294 // Token position remains unchanged. |
5407 bool Parser::IsFunctionTypeAliasName(bool* use_function_type_syntax) { | 5295 bool Parser::IsFunctionTypeAliasName(bool* use_function_type_syntax) { |
5408 if (IsIdentifier()) { | 5296 if (IsIdentifier()) { |
5409 const Token::Kind ahead = LookaheadToken(1); | 5297 const Token::Kind ahead = LookaheadToken(1); |
5410 if ((ahead == Token::kLPAREN) || (ahead == Token::kASSIGN)) { | 5298 if ((ahead == Token::kLPAREN) || (ahead == Token::kASSIGN)) { |
5411 *use_function_type_syntax = (ahead == Token::kASSIGN); | 5299 *use_function_type_syntax = (ahead == Token::kASSIGN); |
5412 return true; | 5300 return true; |
5413 } | 5301 } |
5414 } | 5302 } |
5415 const TokenPosScope saved_pos(this); | 5303 const TokenPosScope saved_pos(this); |
5416 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 5304 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
5417 ConsumeToken(); | 5305 ConsumeToken(); |
5418 if (TryParseTypeParameters()) { | 5306 if (TryParseTypeParameters()) { |
5419 const Token::Kind current = CurrentToken(); | 5307 const Token::Kind current = CurrentToken(); |
5420 if ((current == Token::kLPAREN) || (current == Token::kASSIGN)) { | 5308 if ((current == Token::kLPAREN) || (current == Token::kASSIGN)) { |
5421 *use_function_type_syntax = (current == Token::kASSIGN); | 5309 *use_function_type_syntax = (current == Token::kASSIGN); |
5422 return true; | 5310 return true; |
5423 } | 5311 } |
5424 } | 5312 } |
5425 } | 5313 } |
5426 *use_function_type_syntax = false; | 5314 *use_function_type_syntax = false; |
5427 return false; | 5315 return false; |
5428 } | 5316 } |
5429 | 5317 |
5430 | |
5431 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 5318 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
5432 const Object& tl_owner, | 5319 const Object& tl_owner, |
5433 TokenPosition metadata_pos) { | 5320 TokenPosition metadata_pos) { |
5434 TRACE_PARSER("ParseTypedef"); | 5321 TRACE_PARSER("ParseTypedef"); |
5435 TokenPosition declaration_pos = | 5322 TokenPosition declaration_pos = |
5436 metadata_pos.IsReal() ? metadata_pos : TokenPos(); | 5323 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
5437 ExpectToken(Token::kTYPEDEF); | 5324 ExpectToken(Token::kTYPEDEF); |
5438 | 5325 |
5439 // Distinguish between two possible typedef forms: | 5326 // Distinguish between two possible typedef forms: |
5440 // 1) returnType? identifier typeParameters? formalParameterList ’;’ | 5327 // 1) returnType? identifier typeParameters? formalParameterList ’;’ |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5539 } | 5426 } |
5540 // The alias should not be marked as finalized yet, since it needs to be | 5427 // The alias should not be marked as finalized yet, since it needs to be |
5541 // checked in the class finalizer for illegal self references. | 5428 // checked in the class finalizer for illegal self references. |
5542 ASSERT(!function_type_alias.is_finalized()); | 5429 ASSERT(!function_type_alias.is_finalized()); |
5543 pending_classes.Add(function_type_alias, Heap::kOld); | 5430 pending_classes.Add(function_type_alias, Heap::kOld); |
5544 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5431 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5545 library_.AddClassMetadata(function_type_alias, tl_owner, metadata_pos); | 5432 library_.AddClassMetadata(function_type_alias, tl_owner, metadata_pos); |
5546 } | 5433 } |
5547 } | 5434 } |
5548 | 5435 |
5549 | |
5550 // Consumes exactly one right angle bracket. If the current token is | 5436 // Consumes exactly one right angle bracket. If the current token is |
5551 // a single bracket token, it is consumed normally. However, if it is | 5437 // a single bracket token, it is consumed normally. However, if it is |
5552 // a double bracket, it is replaced by a single bracket token without | 5438 // a double bracket, it is replaced by a single bracket token without |
5553 // incrementing the token index. | 5439 // incrementing the token index. |
5554 void Parser::ConsumeRightAngleBracket() { | 5440 void Parser::ConsumeRightAngleBracket() { |
5555 if (token_kind_ == Token::kGT) { | 5441 if (token_kind_ == Token::kGT) { |
5556 ConsumeToken(); | 5442 ConsumeToken(); |
5557 } else if (token_kind_ == Token::kSHR) { | 5443 } else if (token_kind_ == Token::kSHR) { |
5558 token_kind_ = Token::kGT; | 5444 token_kind_ = Token::kGT; |
5559 } else { | 5445 } else { |
5560 UNREACHABLE(); | 5446 UNREACHABLE(); |
5561 } | 5447 } |
5562 } | 5448 } |
5563 | 5449 |
5564 | |
5565 bool Parser::IsPatchAnnotation(TokenPosition pos) { | 5450 bool Parser::IsPatchAnnotation(TokenPosition pos) { |
5566 if (pos == TokenPosition::kNoSource) { | 5451 if (pos == TokenPosition::kNoSource) { |
5567 return false; | 5452 return false; |
5568 } | 5453 } |
5569 TokenPosScope saved_pos(this); | 5454 TokenPosScope saved_pos(this); |
5570 SetPosition(pos); | 5455 SetPosition(pos); |
5571 ExpectToken(Token::kAT); | 5456 ExpectToken(Token::kAT); |
5572 return IsSymbol(Symbols::Patch()); | 5457 return IsSymbol(Symbols::Patch()); |
5573 } | 5458 } |
5574 | 5459 |
5575 | |
5576 TokenPosition Parser::SkipMetadata() { | 5460 TokenPosition Parser::SkipMetadata() { |
5577 if (CurrentToken() != Token::kAT) { | 5461 if (CurrentToken() != Token::kAT) { |
5578 return TokenPosition::kNoSource; | 5462 return TokenPosition::kNoSource; |
5579 } | 5463 } |
5580 TokenPosition metadata_pos = TokenPos(); | 5464 TokenPosition metadata_pos = TokenPos(); |
5581 while (CurrentToken() == Token::kAT) { | 5465 while (CurrentToken() == Token::kAT) { |
5582 ConsumeToken(); | 5466 ConsumeToken(); |
5583 ExpectIdentifier("identifier expected"); | 5467 ExpectIdentifier("identifier expected"); |
5584 if (CurrentToken() == Token::kPERIOD) { | 5468 if (CurrentToken() == Token::kPERIOD) { |
5585 ConsumeToken(); | 5469 ConsumeToken(); |
5586 ExpectIdentifier("identifier expected"); | 5470 ExpectIdentifier("identifier expected"); |
5587 if (CurrentToken() == Token::kPERIOD) { | 5471 if (CurrentToken() == Token::kPERIOD) { |
5588 ConsumeToken(); | 5472 ConsumeToken(); |
5589 ExpectIdentifier("identifier expected"); | 5473 ExpectIdentifier("identifier expected"); |
5590 } | 5474 } |
5591 } | 5475 } |
5592 if (CurrentToken() == Token::kLPAREN) { | 5476 if (CurrentToken() == Token::kLPAREN) { |
5593 SkipToMatchingParenthesis(); | 5477 SkipToMatchingParenthesis(); |
5594 } | 5478 } |
5595 } | 5479 } |
5596 return metadata_pos; | 5480 return metadata_pos; |
5597 } | 5481 } |
5598 | 5482 |
5599 | |
5600 void Parser::SkipTypeArguments() { | 5483 void Parser::SkipTypeArguments() { |
5601 if (CurrentToken() == Token::kLT) { | 5484 if (CurrentToken() == Token::kLT) { |
5602 do { | 5485 do { |
5603 ConsumeToken(); | 5486 ConsumeToken(); |
5604 SkipTypeOrFunctionType(true); | 5487 SkipTypeOrFunctionType(true); |
5605 } while (CurrentToken() == Token::kCOMMA); | 5488 } while (CurrentToken() == Token::kCOMMA); |
5606 Token::Kind token = CurrentToken(); | 5489 Token::Kind token = CurrentToken(); |
5607 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5490 if ((token == Token::kGT) || (token == Token::kSHR)) { |
5608 ConsumeRightAngleBracket(); | 5491 ConsumeRightAngleBracket(); |
5609 } else { | 5492 } else { |
5610 ReportError("right angle bracket expected"); | 5493 ReportError("right angle bracket expected"); |
5611 } | 5494 } |
5612 } | 5495 } |
5613 } | 5496 } |
5614 | 5497 |
5615 | |
5616 void Parser::SkipTypeParameters() { | 5498 void Parser::SkipTypeParameters() { |
5617 // Function already parsed, no need to check FLAG_generic_method_syntax. | 5499 // Function already parsed, no need to check FLAG_generic_method_syntax. |
5618 if (IsTypeParameters()) { | 5500 if (IsTypeParameters()) { |
5619 const bool skipped = TryParseTypeParameters(); | 5501 const bool skipped = TryParseTypeParameters(); |
5620 ASSERT(skipped); | 5502 ASSERT(skipped); |
5621 } | 5503 } |
5622 } | 5504 } |
5623 | 5505 |
5624 | |
5625 void Parser::SkipType(bool allow_void) { | 5506 void Parser::SkipType(bool allow_void) { |
5626 if (CurrentToken() == Token::kVOID) { | 5507 if (CurrentToken() == Token::kVOID) { |
5627 if (!allow_void) { | 5508 if (!allow_void) { |
5628 ReportError("'void' not allowed here"); | 5509 ReportError("'void' not allowed here"); |
5629 } | 5510 } |
5630 ConsumeToken(); | 5511 ConsumeToken(); |
5631 } else { | 5512 } else { |
5632 ExpectIdentifier("type name expected"); | 5513 ExpectIdentifier("type name expected"); |
5633 if (CurrentToken() == Token::kPERIOD) { | 5514 if (CurrentToken() == Token::kPERIOD) { |
5634 ConsumeToken(); | 5515 ConsumeToken(); |
5635 ExpectIdentifier("name expected"); | 5516 ExpectIdentifier("name expected"); |
5636 } | 5517 } |
5637 SkipTypeArguments(); | 5518 SkipTypeArguments(); |
5638 } | 5519 } |
5639 } | 5520 } |
5640 | 5521 |
5641 | |
5642 void Parser::SkipTypeOrFunctionType(bool allow_void) { | 5522 void Parser::SkipTypeOrFunctionType(bool allow_void) { |
5643 if (CurrentToken() == Token::kVOID) { | 5523 if (CurrentToken() == Token::kVOID) { |
5644 TokenPosition void_pos = TokenPos(); | 5524 TokenPosition void_pos = TokenPos(); |
5645 ConsumeToken(); | 5525 ConsumeToken(); |
5646 // 'void' is always allowed as result type of a function type. | 5526 // 'void' is always allowed as result type of a function type. |
5647 if (!allow_void && !IsFunctionTypeSymbol()) { | 5527 if (!allow_void && !IsFunctionTypeSymbol()) { |
5648 ReportError(void_pos, "'void' not allowed here"); | 5528 ReportError(void_pos, "'void' not allowed here"); |
5649 } | 5529 } |
5650 } else if (!IsFunctionTypeSymbol()) { | 5530 } else if (!IsFunctionTypeSymbol()) { |
5651 // Including 'Function' not followed by '(' or '<'. | 5531 // Including 'Function' not followed by '(' or '<'. |
5652 SkipType(false); | 5532 SkipType(false); |
5653 } | 5533 } |
5654 while (IsFunctionTypeSymbol()) { | 5534 while (IsFunctionTypeSymbol()) { |
5655 ConsumeToken(); | 5535 ConsumeToken(); |
5656 SkipTypeArguments(); | 5536 SkipTypeArguments(); |
5657 if (CurrentToken() == Token::kLPAREN) { | 5537 if (CurrentToken() == Token::kLPAREN) { |
5658 SkipToMatchingParenthesis(); | 5538 SkipToMatchingParenthesis(); |
5659 } else { | 5539 } else { |
5660 ReportError("'(' expected"); | 5540 ReportError("'(' expected"); |
5661 } | 5541 } |
5662 } | 5542 } |
5663 } | 5543 } |
5664 | 5544 |
5665 | |
5666 void Parser::ParseTypeParameters(bool parameterizing_class) { | 5545 void Parser::ParseTypeParameters(bool parameterizing_class) { |
5667 TRACE_PARSER("ParseTypeParameters"); | 5546 TRACE_PARSER("ParseTypeParameters"); |
5668 if (CurrentToken() == Token::kLT) { | 5547 if (CurrentToken() == Token::kLT) { |
5669 GrowableArray<AbstractType*> type_parameters_array(Z, 2); | 5548 GrowableArray<AbstractType*> type_parameters_array(Z, 2); |
5670 intptr_t index = 0; | 5549 intptr_t index = 0; |
5671 TypeParameter& type_parameter = TypeParameter::Handle(Z); | 5550 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
5672 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); | 5551 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
5673 String& existing_type_parameter_name = String::Handle(Z); | 5552 String& existing_type_parameter_name = String::Handle(Z); |
5674 AbstractType& type_parameter_bound = Type::Handle(Z); | 5553 AbstractType& type_parameter_bound = Type::Handle(Z); |
5675 do { | 5554 do { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5740 const intptr_t num_types = type_parameters.Length(); | 5619 const intptr_t num_types = type_parameters.Length(); |
5741 for (intptr_t i = 0; i < num_types; i++) { | 5620 for (intptr_t i = 0; i < num_types; i++) { |
5742 type_parameter ^= type_parameters.TypeAt(i); | 5621 type_parameter ^= type_parameters.TypeAt(i); |
5743 type_parameter_bound = type_parameter.bound(); | 5622 type_parameter_bound = type_parameter.bound(); |
5744 ResolveType(&type_parameter_bound); | 5623 ResolveType(&type_parameter_bound); |
5745 type_parameter.set_bound(type_parameter_bound); | 5624 type_parameter.set_bound(type_parameter_bound); |
5746 } | 5625 } |
5747 } | 5626 } |
5748 } | 5627 } |
5749 | 5628 |
5750 | |
5751 RawTypeArguments* Parser::ParseTypeArguments( | 5629 RawTypeArguments* Parser::ParseTypeArguments( |
5752 ClassFinalizer::FinalizationKind finalization) { | 5630 ClassFinalizer::FinalizationKind finalization) { |
5753 TRACE_PARSER("ParseTypeArguments"); | 5631 TRACE_PARSER("ParseTypeArguments"); |
5754 if (CurrentToken() == Token::kLT) { | 5632 if (CurrentToken() == Token::kLT) { |
5755 GrowableArray<AbstractType*> types; | 5633 GrowableArray<AbstractType*> types; |
5756 AbstractType& type = AbstractType::Handle(Z); | 5634 AbstractType& type = AbstractType::Handle(Z); |
5757 do { | 5635 do { |
5758 ConsumeToken(); | 5636 ConsumeToken(); |
5759 type = ParseTypeOrFunctionType(true, finalization); | 5637 type = ParseTypeOrFunctionType(true, finalization); |
5760 // Map a malformed type argument to dynamic. | 5638 // Map a malformed type argument to dynamic. |
(...skipping 12 matching lines...) Expand all Loading... |
5773 TypeArguments& type_args = TypeArguments::Handle(NewTypeArguments(types)); | 5651 TypeArguments& type_args = TypeArguments::Handle(NewTypeArguments(types)); |
5774 if (finalization == ClassFinalizer::kCanonicalize) { | 5652 if (finalization == ClassFinalizer::kCanonicalize) { |
5775 type_args = type_args.Canonicalize(); | 5653 type_args = type_args.Canonicalize(); |
5776 } | 5654 } |
5777 return type_args.raw(); | 5655 return type_args.raw(); |
5778 } | 5656 } |
5779 } | 5657 } |
5780 return TypeArguments::null(); | 5658 return TypeArguments::null(); |
5781 } | 5659 } |
5782 | 5660 |
5783 | |
5784 // Parse interface list and add to class cls. | 5661 // Parse interface list and add to class cls. |
5785 void Parser::ParseInterfaceList(const Class& cls) { | 5662 void Parser::ParseInterfaceList(const Class& cls) { |
5786 TRACE_PARSER("ParseInterfaceList"); | 5663 TRACE_PARSER("ParseInterfaceList"); |
5787 ASSERT(CurrentToken() == Token::kIMPLEMENTS); | 5664 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
5788 const GrowableObjectArray& all_interfaces = | 5665 const GrowableObjectArray& all_interfaces = |
5789 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 5666 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
5790 AbstractType& interface = AbstractType::Handle(Z); | 5667 AbstractType& interface = AbstractType::Handle(Z); |
5791 // First get all the interfaces already implemented by class. | 5668 // First get all the interfaces already implemented by class. |
5792 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); | 5669 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); |
5793 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 5670 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
5794 interface ^= cls_interfaces.At(i); | 5671 interface ^= cls_interfaces.At(i); |
5795 all_interfaces.Add(interface, Heap::kOld); | 5672 all_interfaces.Add(interface, Heap::kOld); |
5796 } | 5673 } |
5797 // Now parse and add the new interfaces. | 5674 // Now parse and add the new interfaces. |
5798 do { | 5675 do { |
5799 ConsumeToken(); | 5676 ConsumeToken(); |
5800 TokenPosition interface_pos = TokenPos(); | 5677 TokenPosition interface_pos = TokenPos(); |
5801 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 5678 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
5802 if (interface.IsTypeParameter()) { | 5679 if (interface.IsTypeParameter()) { |
5803 ReportError(interface_pos, | 5680 ReportError(interface_pos, |
5804 "type parameter '%s' may not be used in interface list", | 5681 "type parameter '%s' may not be used in interface list", |
5805 String::Handle(Z, interface.UserVisibleName()).ToCString()); | 5682 String::Handle(Z, interface.UserVisibleName()).ToCString()); |
5806 } | 5683 } |
5807 all_interfaces.Add(interface, Heap::kOld); | 5684 all_interfaces.Add(interface, Heap::kOld); |
5808 } while (CurrentToken() == Token::kCOMMA); | 5685 } while (CurrentToken() == Token::kCOMMA); |
5809 cls_interfaces = Array::MakeFixedLength(all_interfaces); | 5686 cls_interfaces = Array::MakeFixedLength(all_interfaces); |
5810 cls.set_interfaces(cls_interfaces); | 5687 cls.set_interfaces(cls_interfaces); |
5811 } | 5688 } |
5812 | 5689 |
5813 | |
5814 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 5690 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
5815 TRACE_PARSER("ParseMixins"); | 5691 TRACE_PARSER("ParseMixins"); |
5816 ASSERT(CurrentToken() == Token::kWITH); | 5692 ASSERT(CurrentToken() == Token::kWITH); |
5817 const GrowableObjectArray& mixin_types = | 5693 const GrowableObjectArray& mixin_types = |
5818 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 5694 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
5819 AbstractType& mixin_type = AbstractType::Handle(Z); | 5695 AbstractType& mixin_type = AbstractType::Handle(Z); |
5820 do { | 5696 do { |
5821 ConsumeToken(); | 5697 ConsumeToken(); |
5822 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5698 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
5823 if (mixin_type.IsDynamicType()) { | 5699 if (mixin_type.IsDynamicType()) { |
5824 // The string 'dynamic' is not resolved yet at this point, but a malformed | 5700 // The string 'dynamic' is not resolved yet at this point, but a malformed |
5825 // type mapped to dynamic can be encountered here. | 5701 // type mapped to dynamic can be encountered here. |
5826 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); | 5702 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); |
5827 } | 5703 } |
5828 if (mixin_type.IsTypeParameter()) { | 5704 if (mixin_type.IsTypeParameter()) { |
5829 ReportError(mixin_type.token_pos(), | 5705 ReportError(mixin_type.token_pos(), |
5830 "mixin type '%s' may not be a type parameter", | 5706 "mixin type '%s' may not be a type parameter", |
5831 String::Handle(Z, mixin_type.UserVisibleName()).ToCString()); | 5707 String::Handle(Z, mixin_type.UserVisibleName()).ToCString()); |
5832 } | 5708 } |
5833 mixin_types.Add(mixin_type, Heap::kOld); | 5709 mixin_types.Add(mixin_type, Heap::kOld); |
5834 } while (CurrentToken() == Token::kCOMMA); | 5710 } while (CurrentToken() == Token::kCOMMA); |
5835 return MixinAppType::New( | 5711 return MixinAppType::New( |
5836 super_type, Array::Handle(Z, Array::MakeFixedLength(mixin_types))); | 5712 super_type, Array::Handle(Z, Array::MakeFixedLength(mixin_types))); |
5837 } | 5713 } |
5838 | 5714 |
5839 | |
5840 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 5715 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
5841 const Object& owner, | 5716 const Object& owner, |
5842 TokenPosition metadata_pos) { | 5717 TokenPosition metadata_pos) { |
5843 TRACE_PARSER("ParseTopLevelVariable"); | 5718 TRACE_PARSER("ParseTopLevelVariable"); |
5844 const bool is_const = (CurrentToken() == Token::kCONST); | 5719 const bool is_const = (CurrentToken() == Token::kCONST); |
5845 // Const fields are implicitly final. | 5720 // Const fields are implicitly final. |
5846 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 5721 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
5847 const bool is_static = true; | 5722 const bool is_static = true; |
5848 const AbstractType& type = AbstractType::ZoneHandle( | 5723 const AbstractType& type = AbstractType::ZoneHandle( |
5849 Z, ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 5724 Z, ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5920 ConsumeToken(); | 5795 ConsumeToken(); |
5921 } else if (CurrentToken() == Token::kSEMICOLON) { | 5796 } else if (CurrentToken() == Token::kSEMICOLON) { |
5922 ConsumeToken(); | 5797 ConsumeToken(); |
5923 break; | 5798 break; |
5924 } else { | 5799 } else { |
5925 ExpectSemicolon(); // Reports error. | 5800 ExpectSemicolon(); // Reports error. |
5926 } | 5801 } |
5927 } | 5802 } |
5928 } | 5803 } |
5929 | 5804 |
5930 | |
5931 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { | 5805 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { |
5932 if (IsSymbol(Symbols::Async())) { | 5806 if (IsSymbol(Symbols::Async())) { |
5933 ConsumeToken(); | 5807 ConsumeToken(); |
5934 if (CurrentToken() == Token::kMUL) { | 5808 if (CurrentToken() == Token::kMUL) { |
5935 const bool enableAsyncStar = true; | 5809 const bool enableAsyncStar = true; |
5936 if (!enableAsyncStar) { | 5810 if (!enableAsyncStar) { |
5937 ReportError("async* generator functions are not yet supported"); | 5811 ReportError("async* generator functions are not yet supported"); |
5938 } | 5812 } |
5939 ConsumeToken(); | 5813 ConsumeToken(); |
5940 return RawFunction::kAsyncGen; | 5814 return RawFunction::kAsyncGen; |
5941 } else { | 5815 } else { |
5942 return RawFunction::kAsync; | 5816 return RawFunction::kAsync; |
5943 } | 5817 } |
5944 } else if (IsSymbol(Symbols::Sync()) && (LookaheadToken(1) == Token::kMUL)) { | 5818 } else if (IsSymbol(Symbols::Sync()) && (LookaheadToken(1) == Token::kMUL)) { |
5945 const bool enableSyncStar = true; | 5819 const bool enableSyncStar = true; |
5946 if (!enableSyncStar) { | 5820 if (!enableSyncStar) { |
5947 ReportError("sync* generator functions are not yet supported"); | 5821 ReportError("sync* generator functions are not yet supported"); |
5948 } | 5822 } |
5949 ConsumeToken(); | 5823 ConsumeToken(); |
5950 ConsumeToken(); | 5824 ConsumeToken(); |
5951 return RawFunction::kSyncGen; | 5825 return RawFunction::kSyncGen; |
5952 } | 5826 } |
5953 return RawFunction::kNoModifier; | 5827 return RawFunction::kNoModifier; |
5954 } | 5828 } |
5955 | 5829 |
5956 | |
5957 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5830 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
5958 const Object& owner, | 5831 const Object& owner, |
5959 TokenPosition metadata_pos) { | 5832 TokenPosition metadata_pos) { |
5960 TRACE_PARSER("ParseTopLevelFunction"); | 5833 TRACE_PARSER("ParseTopLevelFunction"); |
5961 const TokenPosition decl_begin_pos = TokenPos(); | 5834 const TokenPosition decl_begin_pos = TokenPos(); |
5962 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 5835 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
5963 bool is_external = false; | 5836 bool is_external = false; |
5964 bool is_patch = false; | 5837 bool is_patch = false; |
5965 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 5838 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
5966 is_patch = true; | 5839 is_patch = true; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6079 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); | 5952 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); |
6080 ASSERT(!replaced_func.IsNull()); | 5953 ASSERT(!replaced_func.IsNull()); |
6081 toplevel_cls.RemoveFunction(replaced_func); | 5954 toplevel_cls.RemoveFunction(replaced_func); |
6082 library_.ReplaceObject(func, func_name); | 5955 library_.ReplaceObject(func, func_name); |
6083 } | 5956 } |
6084 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5957 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
6085 library_.AddFunctionMetadata(func, metadata_pos); | 5958 library_.AddFunctionMetadata(func, metadata_pos); |
6086 } | 5959 } |
6087 } | 5960 } |
6088 | 5961 |
6089 | |
6090 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 5962 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
6091 const Object& owner, | 5963 const Object& owner, |
6092 TokenPosition metadata_pos) { | 5964 TokenPosition metadata_pos) { |
6093 TRACE_PARSER("ParseTopLevelAccessor"); | 5965 TRACE_PARSER("ParseTopLevelAccessor"); |
6094 const TokenPosition decl_begin_pos = TokenPos(); | 5966 const TokenPosition decl_begin_pos = TokenPos(); |
6095 const bool is_static = true; | 5967 const bool is_static = true; |
6096 bool is_external = false; | 5968 bool is_external = false; |
6097 bool is_patch = false; | 5969 bool is_patch = false; |
6098 AbstractType& result_type = AbstractType::Handle(Z); | 5970 AbstractType& result_type = AbstractType::Handle(Z); |
6099 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 5971 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6199 ExpectSemicolon(); | 6071 ExpectSemicolon(); |
6200 } else if (IsSymbol(Symbols::Native())) { | 6072 } else if (IsSymbol(Symbols::Native())) { |
6201 native_name = &ParseNativeDeclaration(); | 6073 native_name = &ParseNativeDeclaration(); |
6202 accessor_end_pos = TokenPos(); | 6074 accessor_end_pos = TokenPos(); |
6203 ExpectSemicolon(); | 6075 ExpectSemicolon(); |
6204 is_native = true; | 6076 is_native = true; |
6205 } else { | 6077 } else { |
6206 ReportError("function block expected"); | 6078 ReportError("function block expected"); |
6207 } | 6079 } |
6208 Function& func = Function::Handle( | 6080 Function& func = Function::Handle( |
6209 Z, Function::New(accessor_name, is_getter ? RawFunction::kGetterFunction | 6081 Z, Function::New(accessor_name, |
6210 : RawFunction::kSetterFunction, | 6082 is_getter ? RawFunction::kGetterFunction |
| 6083 : RawFunction::kSetterFunction, |
6211 is_static, | 6084 is_static, |
6212 /* is_const = */ false, | 6085 /* is_const = */ false, |
6213 /* is_abstract = */ false, is_external, is_native, owner, | 6086 /* is_abstract = */ false, is_external, is_native, owner, |
6214 decl_begin_pos)); | 6087 decl_begin_pos)); |
6215 func.set_result_type(result_type); | 6088 func.set_result_type(result_type); |
6216 func.set_end_token_pos(accessor_end_pos); | 6089 func.set_end_token_pos(accessor_end_pos); |
6217 func.set_modifier(func_modifier); | 6090 func.set_modifier(func_modifier); |
6218 if (is_native) { | 6091 if (is_native) { |
6219 func.set_is_debuggable(false); | 6092 func.set_is_debuggable(false); |
6220 func.set_native_name(*native_name); | 6093 func.set_native_name(*native_name); |
(...skipping 15 matching lines...) Expand all Loading... |
6236 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); | 6109 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); |
6237 ASSERT(!replaced_func.IsNull()); | 6110 ASSERT(!replaced_func.IsNull()); |
6238 toplevel_cls.RemoveFunction(replaced_func); | 6111 toplevel_cls.RemoveFunction(replaced_func); |
6239 library_.ReplaceObject(func, accessor_name); | 6112 library_.ReplaceObject(func, accessor_name); |
6240 } | 6113 } |
6241 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 6114 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
6242 library_.AddFunctionMetadata(func, metadata_pos); | 6115 library_.AddFunctionMetadata(func, metadata_pos); |
6243 } | 6116 } |
6244 } | 6117 } |
6245 | 6118 |
6246 | |
6247 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, | 6119 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, |
6248 TokenPosition token_pos, | 6120 TokenPosition token_pos, |
6249 const String& url) { | 6121 const String& url) { |
6250 Dart_LibraryTagHandler handler = I->library_tag_handler(); | 6122 Dart_LibraryTagHandler handler = I->library_tag_handler(); |
6251 if (handler == NULL) { | 6123 if (handler == NULL) { |
6252 if (url.StartsWith(Symbols::DartScheme())) { | 6124 if (url.StartsWith(Symbols::DartScheme())) { |
6253 if (tag == Dart_kCanonicalizeUrl) { | 6125 if (tag == Dart_kCanonicalizeUrl) { |
6254 return url.raw(); | 6126 return url.raw(); |
6255 } | 6127 } |
6256 return Object::null(); | 6128 return Object::null(); |
(...skipping 19 matching lines...) Expand all Loading... |
6276 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); | 6148 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); |
6277 } | 6149 } |
6278 if (tag == Dart_kCanonicalizeUrl) { | 6150 if (tag == Dart_kCanonicalizeUrl) { |
6279 if (!result.IsString()) { | 6151 if (!result.IsString()) { |
6280 ReportError(token_pos, "library handler failed URI canonicalization"); | 6152 ReportError(token_pos, "library handler failed URI canonicalization"); |
6281 } | 6153 } |
6282 } | 6154 } |
6283 return result.raw(); | 6155 return result.raw(); |
6284 } | 6156 } |
6285 | 6157 |
6286 | |
6287 void Parser::ParseLibraryName() { | 6158 void Parser::ParseLibraryName() { |
6288 ASSERT(CurrentToken() == Token::kLIBRARY); | 6159 ASSERT(CurrentToken() == Token::kLIBRARY); |
6289 ConsumeToken(); | 6160 ConsumeToken(); |
6290 String& lib_name = *ExpectIdentifier("library name expected"); | 6161 String& lib_name = *ExpectIdentifier("library name expected"); |
6291 if (CurrentToken() == Token::kPERIOD) { | 6162 if (CurrentToken() == Token::kPERIOD) { |
6292 GrowableHandlePtrArray<const String> pieces(Z, 3); | 6163 GrowableHandlePtrArray<const String> pieces(Z, 3); |
6293 pieces.Add(lib_name); | 6164 pieces.Add(lib_name); |
6294 while (CurrentToken() == Token::kPERIOD) { | 6165 while (CurrentToken() == Token::kPERIOD) { |
6295 ConsumeToken(); | 6166 ConsumeToken(); |
6296 pieces.Add(Symbols::Dot()); | 6167 pieces.Add(Symbols::Dot()); |
6297 pieces.Add(*ExpectIdentifier("malformed library name")); | 6168 pieces.Add(*ExpectIdentifier("malformed library name")); |
6298 } | 6169 } |
6299 lib_name = Symbols::FromConcatAll(T, pieces); | 6170 lib_name = Symbols::FromConcatAll(T, pieces); |
6300 } | 6171 } |
6301 library_.SetName(lib_name); | 6172 library_.SetName(lib_name); |
6302 ExpectSemicolon(); | 6173 ExpectSemicolon(); |
6303 } | 6174 } |
6304 | 6175 |
6305 | |
6306 void Parser::ParseIdentList(GrowableObjectArray* names) { | 6176 void Parser::ParseIdentList(GrowableObjectArray* names) { |
6307 if (!IsIdentifier()) { | 6177 if (!IsIdentifier()) { |
6308 ReportError("identifier expected"); | 6178 ReportError("identifier expected"); |
6309 } | 6179 } |
6310 while (IsIdentifier()) { | 6180 while (IsIdentifier()) { |
6311 names->Add(*CurrentLiteral(), allocation_space_); | 6181 names->Add(*CurrentLiteral(), allocation_space_); |
6312 ConsumeToken(); // Identifier. | 6182 ConsumeToken(); // Identifier. |
6313 if (CurrentToken() != Token::kCOMMA) { | 6183 if (CurrentToken() != Token::kCOMMA) { |
6314 return; | 6184 return; |
6315 } | 6185 } |
6316 ConsumeToken(); // Comma. | 6186 ConsumeToken(); // Comma. |
6317 } | 6187 } |
6318 } | 6188 } |
6319 | 6189 |
6320 | |
6321 void Parser::ParseLibraryImportExport(const Object& tl_owner, | 6190 void Parser::ParseLibraryImportExport(const Object& tl_owner, |
6322 TokenPosition metadata_pos) { | 6191 TokenPosition metadata_pos) { |
6323 ASSERT(Thread::Current()->IsMutatorThread()); | 6192 ASSERT(Thread::Current()->IsMutatorThread()); |
6324 bool is_import = (CurrentToken() == Token::kIMPORT); | 6193 bool is_import = (CurrentToken() == Token::kIMPORT); |
6325 bool is_export = (CurrentToken() == Token::kEXPORT); | 6194 bool is_export = (CurrentToken() == Token::kEXPORT); |
6326 ASSERT(is_import || is_export); | 6195 ASSERT(is_import || is_export); |
6327 const TokenPosition import_pos = TokenPos(); | 6196 const TokenPosition import_pos = TokenPos(); |
6328 ConsumeToken(); | 6197 ConsumeToken(); |
6329 CheckToken(Token::kSTRING, "library url expected"); | 6198 CheckToken(Token::kSTRING, "library url expected"); |
6330 AstNode* url_literal = ParseStringLiteral(false); | 6199 AstNode* url_literal = ParseStringLiteral(false); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6492 LibraryPrefix::New(prefix, ns, is_deferred_import, library_); | 6361 LibraryPrefix::New(prefix, ns, is_deferred_import, library_); |
6493 library_.AddObject(library_prefix, prefix); | 6362 library_.AddObject(library_prefix, prefix); |
6494 } | 6363 } |
6495 } | 6364 } |
6496 } else { | 6365 } else { |
6497 ASSERT(is_export); | 6366 ASSERT(is_export); |
6498 library_.AddExport(ns); | 6367 library_.AddExport(ns); |
6499 } | 6368 } |
6500 } | 6369 } |
6501 | 6370 |
6502 | |
6503 void Parser::ParseLibraryPart() { | 6371 void Parser::ParseLibraryPart() { |
6504 const TokenPosition source_pos = TokenPos(); | 6372 const TokenPosition source_pos = TokenPos(); |
6505 ConsumeToken(); // Consume "part". | 6373 ConsumeToken(); // Consume "part". |
6506 if (IsSymbol(Symbols::Of())) { | 6374 if (IsSymbol(Symbols::Of())) { |
6507 ReportError("part of declarations are not allowed in script files"); | 6375 ReportError("part of declarations are not allowed in script files"); |
6508 } | 6376 } |
6509 CheckToken(Token::kSTRING, "url expected"); | 6377 CheckToken(Token::kSTRING, "url expected"); |
6510 AstNode* url_literal = ParseStringLiteral(false); | 6378 AstNode* url_literal = ParseStringLiteral(false); |
6511 ASSERT(url_literal->IsLiteralNode()); | 6379 ASSERT(url_literal->IsLiteralNode()); |
6512 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 6380 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
6513 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 6381 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
6514 ExpectSemicolon(); | 6382 ExpectSemicolon(); |
6515 const String& canon_url = String::CheckedHandle( | 6383 const String& canon_url = String::CheckedHandle( |
6516 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); | 6384 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); |
6517 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); | 6385 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); |
6518 } | 6386 } |
6519 | 6387 |
6520 | |
6521 void Parser::ParseLibraryDefinition(const Object& tl_owner) { | 6388 void Parser::ParseLibraryDefinition(const Object& tl_owner) { |
6522 TRACE_PARSER("ParseLibraryDefinition"); | 6389 TRACE_PARSER("ParseLibraryDefinition"); |
6523 | 6390 |
6524 // Handle the script tag. | 6391 // Handle the script tag. |
6525 if (CurrentToken() == Token::kSCRIPTTAG) { | 6392 if (CurrentToken() == Token::kSCRIPTTAG) { |
6526 // Nothing to do for script tags except to skip them. | 6393 // Nothing to do for script tags except to skip them. |
6527 ConsumeToken(); | 6394 ConsumeToken(); |
6528 } | 6395 } |
6529 | 6396 |
6530 ASSERT(script_.kind() != RawScript::kSourceTag); | 6397 ASSERT(script_.kind() != RawScript::kSourceTag); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6563 library_.AddImport(core_ns); | 6430 library_.AddImport(core_ns); |
6564 } | 6431 } |
6565 while (CurrentToken() == Token::kPART) { | 6432 while (CurrentToken() == Token::kPART) { |
6566 ParseLibraryPart(); | 6433 ParseLibraryPart(); |
6567 rewind_pos = TokenPos(); | 6434 rewind_pos = TokenPos(); |
6568 metadata_pos = SkipMetadata(); | 6435 metadata_pos = SkipMetadata(); |
6569 } | 6436 } |
6570 SetPosition(rewind_pos); | 6437 SetPosition(rewind_pos); |
6571 } | 6438 } |
6572 | 6439 |
6573 | |
6574 void Parser::ParsePartHeader() { | 6440 void Parser::ParsePartHeader() { |
6575 SkipMetadata(); | 6441 SkipMetadata(); |
6576 CheckToken(Token::kPART, "'part of' expected"); | 6442 CheckToken(Token::kPART, "'part of' expected"); |
6577 ConsumeToken(); | 6443 ConsumeToken(); |
6578 if (!IsSymbol(Symbols::Of())) { | 6444 if (!IsSymbol(Symbols::Of())) { |
6579 ReportError("'part of' expected"); | 6445 ReportError("'part of' expected"); |
6580 } | 6446 } |
6581 ConsumeToken(); | 6447 ConsumeToken(); |
6582 // The VM is not required to check that the library name or URI matches the | 6448 // The VM is not required to check that the library name or URI matches the |
6583 // name or URI of the current library, so we ignore them. | 6449 // name or URI of the current library, so we ignore them. |
6584 if (CurrentToken() == Token::kSTRING) { | 6450 if (CurrentToken() == Token::kSTRING) { |
6585 ParseStringLiteral(false); | 6451 ParseStringLiteral(false); |
6586 } else { | 6452 } else { |
6587 ExpectIdentifier("library name expected"); | 6453 ExpectIdentifier("library name expected"); |
6588 while (CurrentToken() == Token::kPERIOD) { | 6454 while (CurrentToken() == Token::kPERIOD) { |
6589 ConsumeToken(); | 6455 ConsumeToken(); |
6590 ExpectIdentifier("malformed library name"); | 6456 ExpectIdentifier("malformed library name"); |
6591 } | 6457 } |
6592 } | 6458 } |
6593 ExpectSemicolon(); | 6459 ExpectSemicolon(); |
6594 } | 6460 } |
6595 | 6461 |
6596 | |
6597 void Parser::ParseTopLevel() { | 6462 void Parser::ParseTopLevel() { |
6598 TRACE_PARSER("ParseTopLevel"); | 6463 TRACE_PARSER("ParseTopLevel"); |
6599 // Collect the classes found at the top level in this growable array. | 6464 // Collect the classes found at the top level in this growable array. |
6600 // They need to be registered with class finalization after parsing | 6465 // They need to be registered with class finalization after parsing |
6601 // has been completed. | 6466 // has been completed. |
6602 ObjectStore* object_store = I->object_store(); | 6467 ObjectStore* object_store = I->object_store(); |
6603 const GrowableObjectArray& pending_classes = | 6468 const GrowableObjectArray& pending_classes = |
6604 GrowableObjectArray::Handle(Z, object_store->pending_classes()); | 6469 GrowableObjectArray::Handle(Z, object_store->pending_classes()); |
6605 SetPosition(TokenPosition::kMinSource); | 6470 SetPosition(TokenPosition::kMinSource); |
6606 is_top_level_ = true; | 6471 is_top_level_ = true; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6661 } | 6526 } |
6662 for (intptr_t i = 0; i < top_level.functions().length(); i++) { | 6527 for (intptr_t i = 0; i < top_level.functions().length(); i++) { |
6663 toplevel_class.AddFunction(*top_level.functions()[i]); | 6528 toplevel_class.AddFunction(*top_level.functions()[i]); |
6664 } | 6529 } |
6665 if (toplevel_class.is_finalized()) { | 6530 if (toplevel_class.is_finalized()) { |
6666 toplevel_class.ResetFinalization(); | 6531 toplevel_class.ResetFinalization(); |
6667 } | 6532 } |
6668 pending_classes.Add(toplevel_class, Heap::kOld); | 6533 pending_classes.Add(toplevel_class, Heap::kOld); |
6669 } | 6534 } |
6670 | 6535 |
6671 | |
6672 void Parser::CheckStack() { | 6536 void Parser::CheckStack() { |
6673 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); | 6537 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); |
6674 volatile uword c_stack_base = OSThread::Current()->stack_base(); | 6538 volatile uword c_stack_base = OSThread::Current()->stack_base(); |
6675 volatile uword c_stack_limit = | 6539 volatile uword c_stack_limit = |
6676 c_stack_base - OSThread::GetSpecifiedStackSize(); | 6540 c_stack_base - OSThread::GetSpecifiedStackSize(); |
6677 // Note: during early initialization the stack_base() can return 0. | 6541 // Note: during early initialization the stack_base() can return 0. |
6678 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { | 6542 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { |
6679 ReportError("stack overflow while parsing"); | 6543 ReportError("stack overflow while parsing"); |
6680 } | 6544 } |
6681 } | 6545 } |
6682 | 6546 |
6683 | |
6684 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 6547 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
6685 Block* block = new (Z) Block(current_block_, outer_scope, | 6548 Block* block = new (Z) Block(current_block_, outer_scope, |
6686 new (Z) SequenceNode(TokenPos(), outer_scope)); | 6549 new (Z) SequenceNode(TokenPos(), outer_scope)); |
6687 current_block_ = block; | 6550 current_block_ = block; |
6688 } | 6551 } |
6689 | 6552 |
6690 | |
6691 void Parser::OpenBlock() { | 6553 void Parser::OpenBlock() { |
6692 ASSERT(current_block_ != NULL); | 6554 ASSERT(current_block_ != NULL); |
6693 LocalScope* outer_scope = current_block_->scope; | 6555 LocalScope* outer_scope = current_block_->scope; |
6694 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), | 6556 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), |
6695 outer_scope->loop_level())); | 6557 outer_scope->loop_level())); |
6696 } | 6558 } |
6697 | 6559 |
6698 | |
6699 void Parser::OpenLoopBlock() { | 6560 void Parser::OpenLoopBlock() { |
6700 ASSERT(current_block_ != NULL); | 6561 ASSERT(current_block_ != NULL); |
6701 LocalScope* outer_scope = current_block_->scope; | 6562 LocalScope* outer_scope = current_block_->scope; |
6702 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), | 6563 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), |
6703 outer_scope->loop_level() + 1)); | 6564 outer_scope->loop_level() + 1)); |
6704 } | 6565 } |
6705 | 6566 |
6706 | |
6707 void Parser::OpenFunctionBlock(const Function& func) { | 6567 void Parser::OpenFunctionBlock(const Function& func) { |
6708 LocalScope* outer_scope; | 6568 LocalScope* outer_scope; |
6709 if (current_block_ == NULL) { | 6569 if (current_block_ == NULL) { |
6710 if (!func.IsLocalFunction()) { | 6570 if (!func.IsLocalFunction()) { |
6711 // We are compiling a non-nested function. | 6571 // We are compiling a non-nested function. |
6712 outer_scope = new (Z) LocalScope(NULL, 0, 0); | 6572 outer_scope = new (Z) LocalScope(NULL, 0, 0); |
6713 } else { | 6573 } else { |
6714 // We are compiling the function of an invoked closure. | 6574 // We are compiling the function of an invoked closure. |
6715 // Restore the outer scope containing all captured variables. | 6575 // Restore the outer scope containing all captured variables. |
6716 const ContextScope& context_scope = | 6576 const ContextScope& context_scope = |
6717 ContextScope::Handle(Z, func.context_scope()); | 6577 ContextScope::Handle(Z, func.context_scope()); |
6718 ASSERT(!context_scope.IsNull()); | 6578 ASSERT(!context_scope.IsNull()); |
6719 outer_scope = new (Z) | 6579 outer_scope = new (Z) |
6720 LocalScope(LocalScope::RestoreOuterScope(context_scope), 0, 0); | 6580 LocalScope(LocalScope::RestoreOuterScope(context_scope), 0, 0); |
6721 } | 6581 } |
6722 } else { | 6582 } else { |
6723 // We are parsing a nested function while compiling the enclosing function. | 6583 // We are parsing a nested function while compiling the enclosing function. |
6724 outer_scope = new (Z) LocalScope( | 6584 outer_scope = new (Z) LocalScope( |
6725 current_block_->scope, current_block_->scope->function_level() + 1, 0); | 6585 current_block_->scope, current_block_->scope->function_level() + 1, 0); |
6726 } | 6586 } |
6727 ChainNewBlock(outer_scope); | 6587 ChainNewBlock(outer_scope); |
6728 } | 6588 } |
6729 | 6589 |
6730 | |
6731 void Parser::OpenAsyncClosure() { | 6590 void Parser::OpenAsyncClosure() { |
6732 TRACE_PARSER("OpenAsyncClosure"); | 6591 TRACE_PARSER("OpenAsyncClosure"); |
6733 async_temp_scope_ = current_block_->scope; | 6592 async_temp_scope_ = current_block_->scope; |
6734 OpenAsyncTryBlock(); | 6593 OpenAsyncTryBlock(); |
6735 } | 6594 } |
6736 | 6595 |
6737 | |
6738 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode* body) { | 6596 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode* body) { |
6739 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); | 6597 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); |
6740 // The generated try-catch-finally that wraps the async generator function | 6598 // The generated try-catch-finally that wraps the async generator function |
6741 // body is the outermost try statement. | 6599 // body is the outermost try statement. |
6742 ASSERT(try_stack_ != NULL); | 6600 ASSERT(try_stack_ != NULL); |
6743 ASSERT(try_stack_->outer_try() == NULL); | 6601 ASSERT(try_stack_->outer_try() == NULL); |
6744 // We only get here when parsing an async generator body. | 6602 // We only get here when parsing an async generator body. |
6745 ASSERT(innermost_function().IsAsyncGenClosure()); | 6603 ASSERT(innermost_function().IsAsyncGenClosure()); |
6746 | 6604 |
6747 const TokenPosition try_end_pos = innermost_function().end_token_pos(); | 6605 const TokenPosition try_end_pos = innermost_function().end_token_pos(); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6883 | 6741 |
6884 const intptr_t try_index = try_statement->try_index(); | 6742 const intptr_t try_index = try_statement->try_index(); |
6885 | 6743 |
6886 AstNode* try_catch_node = new (Z) | 6744 AstNode* try_catch_node = new (Z) |
6887 TryCatchNode(TokenPosition::kNoSource, body, context_var, catch_clause, | 6745 TryCatchNode(TokenPosition::kNoSource, body, context_var, catch_clause, |
6888 finally_clause, try_index, finally_clause); | 6746 finally_clause, try_index, finally_clause); |
6889 current_block_->statements->Add(try_catch_node); | 6747 current_block_->statements->Add(try_catch_node); |
6890 return CloseBlock(); | 6748 return CloseBlock(); |
6891 } | 6749 } |
6892 | 6750 |
6893 | |
6894 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block, | 6751 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block, |
6895 TokenPosition func_end_pos) { | 6752 TokenPosition func_end_pos) { |
6896 // This is the outermost try-catch of the function. | 6753 // This is the outermost try-catch of the function. |
6897 ASSERT(try_stack_ != NULL); | 6754 ASSERT(try_stack_ != NULL); |
6898 ASSERT(try_stack_->outer_try() == NULL); | 6755 ASSERT(try_stack_->outer_try() == NULL); |
6899 ASSERT(innermost_function().IsAsyncClosure()); | 6756 ASSERT(innermost_function().IsAsyncClosure()); |
6900 LocalScope* try_scope = current_block_->scope; | 6757 LocalScope* try_scope = current_block_->scope; |
6901 | 6758 |
6902 try_stack_->enter_catch(); | 6759 try_stack_->enter_catch(); |
6903 | 6760 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6984 saved_stack_trace_var, CatchClauseNode::kInvalidTryIndex, true); | 6841 saved_stack_trace_var, CatchClauseNode::kInvalidTryIndex, true); |
6985 AstNode* try_catch_node = new (Z) TryCatchNode( | 6842 AstNode* try_catch_node = new (Z) TryCatchNode( |
6986 TokenPosition::kNoSource, try_block, context_var, catch_clause, | 6843 TokenPosition::kNoSource, try_block, context_var, catch_clause, |
6987 NULL, // No finally clause. | 6844 NULL, // No finally clause. |
6988 try_index, | 6845 try_index, |
6989 NULL); // No rethrow-finally clause. | 6846 NULL); // No rethrow-finally clause. |
6990 current_block_->statements->Add(try_catch_node); | 6847 current_block_->statements->Add(try_catch_node); |
6991 return CloseBlock(); | 6848 return CloseBlock(); |
6992 } | 6849 } |
6993 | 6850 |
6994 | |
6995 // Wrap the body of the async or async* closure in a try/catch block. | 6851 // Wrap the body of the async or async* closure in a try/catch block. |
6996 void Parser::OpenAsyncTryBlock() { | 6852 void Parser::OpenAsyncTryBlock() { |
6997 ASSERT(innermost_function().IsAsyncClosure() || | 6853 ASSERT(innermost_function().IsAsyncClosure() || |
6998 innermost_function().IsAsyncGenClosure()); | 6854 innermost_function().IsAsyncGenClosure()); |
6999 LocalVariable* context_var = NULL; | 6855 LocalVariable* context_var = NULL; |
7000 LocalVariable* exception_var = NULL; | 6856 LocalVariable* exception_var = NULL; |
7001 LocalVariable* stack_trace_var = NULL; | 6857 LocalVariable* stack_trace_var = NULL; |
7002 LocalVariable* saved_exception_var = NULL; | 6858 LocalVariable* saved_exception_var = NULL; |
7003 LocalVariable* saved_stack_trace_var = NULL; | 6859 LocalVariable* saved_stack_trace_var = NULL; |
7004 SetupExceptionVariables(current_block_->scope, true, &context_var, | 6860 SetupExceptionVariables(current_block_->scope, true, &context_var, |
7005 &exception_var, &stack_trace_var, | 6861 &exception_var, &stack_trace_var, |
7006 &saved_exception_var, &saved_stack_trace_var); | 6862 &saved_exception_var, &saved_stack_trace_var); |
7007 | 6863 |
7008 // Open the try block. | 6864 // Open the try block. |
7009 OpenBlock(); | 6865 OpenBlock(); |
7010 // This is the outermost try-catch in the function. | 6866 // This is the outermost try-catch in the function. |
7011 ASSERT(try_stack_ == NULL); | 6867 ASSERT(try_stack_ == NULL); |
7012 PushTry(current_block_); | 6868 PushTry(current_block_); |
7013 // Validate that we always get try index of 0. | 6869 // Validate that we always get try index of 0. |
7014 ASSERT(try_stack_->try_index() == CatchClauseNode::kImplicitAsyncTryIndex); | 6870 ASSERT(try_stack_->try_index() == CatchClauseNode::kImplicitAsyncTryIndex); |
7015 | 6871 |
7016 SetupSavedTryContext(context_var); | 6872 SetupSavedTryContext(context_var); |
7017 } | 6873 } |
7018 | 6874 |
7019 | |
7020 void Parser::AddSyncGenClosureParameters(ParamList* params) { | 6875 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
7021 // Create the parameter list for the body closure of a sync generator: | 6876 // Create the parameter list for the body closure of a sync generator: |
7022 // 1) Implicit closure parameter; | 6877 // 1) Implicit closure parameter; |
7023 // 2) Iterator | 6878 // 2) Iterator |
7024 // Add implicit closure parameter if not already present. | 6879 // Add implicit closure parameter if not already present. |
7025 if (params->parameters->length() == 0) { | 6880 if (params->parameters->length() == 0) { |
7026 params->AddFinalParameter(TokenPosition::kMinSource, | 6881 params->AddFinalParameter(TokenPosition::kMinSource, |
7027 &Symbols::ClosureParameter(), | 6882 &Symbols::ClosureParameter(), |
7028 &Object::dynamic_type()); | 6883 &Object::dynamic_type()); |
7029 } | 6884 } |
7030 ParamDesc iterator_param; | 6885 ParamDesc iterator_param; |
7031 iterator_param.name = &Symbols::IteratorParameter(); | 6886 iterator_param.name = &Symbols::IteratorParameter(); |
7032 iterator_param.type = &Object::dynamic_type(); | 6887 iterator_param.type = &Object::dynamic_type(); |
7033 params->parameters->Add(iterator_param); | 6888 params->parameters->Add(iterator_param); |
7034 params->num_fixed_parameters++; | 6889 params->num_fixed_parameters++; |
7035 } | 6890 } |
7036 | 6891 |
7037 | |
7038 void Parser::AddAsyncGenClosureParameters(ParamList* params) { | 6892 void Parser::AddAsyncGenClosureParameters(ParamList* params) { |
7039 // Create the parameter list for the body closure of an async generator. | 6893 // Create the parameter list for the body closure of an async generator. |
7040 // The closure has the same parameters as an asynchronous non-generator. | 6894 // The closure has the same parameters as an asynchronous non-generator. |
7041 AddAsyncClosureParameters(params); | 6895 AddAsyncClosureParameters(params); |
7042 } | 6896 } |
7043 | 6897 |
7044 | |
7045 RawFunction* Parser::OpenSyncGeneratorFunction(TokenPosition func_pos) { | 6898 RawFunction* Parser::OpenSyncGeneratorFunction(TokenPosition func_pos) { |
7046 Function& body = Function::Handle(Z); | 6899 Function& body = Function::Handle(Z); |
7047 String& body_closure_name = String::Handle(Z); | 6900 String& body_closure_name = String::Handle(Z); |
7048 bool is_new_closure = false; | 6901 bool is_new_closure = false; |
7049 | 6902 |
7050 AddContinuationVariables(); | 6903 AddContinuationVariables(); |
7051 | 6904 |
7052 // Check whether a function for the body of this generator | 6905 // Check whether a function for the body of this generator |
7053 // function has already been created by a previous | 6906 // function has already been created by a previous |
7054 // compilation. | 6907 // compilation. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7130 arguments->Add(closure_obj); | 6983 arguments->Add(closure_obj); |
7131 ConstructorCallNode* new_iterable = new (Z) ConstructorCallNode( | 6984 ConstructorCallNode* new_iterable = new (Z) ConstructorCallNode( |
7132 TokenPosition::kNoSource, TypeArguments::ZoneHandle(Z), | 6985 TokenPosition::kNoSource, TypeArguments::ZoneHandle(Z), |
7133 iterable_constructor, arguments); | 6986 iterable_constructor, arguments); |
7134 ReturnNode* return_node = | 6987 ReturnNode* return_node = |
7135 new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable); | 6988 new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable); |
7136 current_block_->statements->Add(return_node); | 6989 current_block_->statements->Add(return_node); |
7137 return CloseBlock(); | 6990 return CloseBlock(); |
7138 } | 6991 } |
7139 | 6992 |
7140 | |
7141 void Parser::AddAsyncClosureParameters(ParamList* params) { | 6993 void Parser::AddAsyncClosureParameters(ParamList* params) { |
7142 // Async closures have three optional parameters: | 6994 // Async closures have three optional parameters: |
7143 // * A continuation result. | 6995 // * A continuation result. |
7144 // * A continuation error. | 6996 // * A continuation error. |
7145 // * A continuation stack trace. | 6997 // * A continuation stack trace. |
7146 ASSERT(params->parameters->length() <= 1); | 6998 ASSERT(params->parameters->length() <= 1); |
7147 // Add implicit closure parameter if not yet present. | 6999 // Add implicit closure parameter if not yet present. |
7148 if (params->parameters->length() == 0) { | 7000 if (params->parameters->length() == 0) { |
7149 params->AddFinalParameter(TokenPosition::kMinSource, | 7001 params->AddFinalParameter(TokenPosition::kMinSource, |
7150 &Symbols::ClosureParameter(), | 7002 &Symbols::ClosureParameter(), |
(...skipping 11 matching lines...) Expand all Loading... |
7162 params->parameters->Add(error_param); | 7014 params->parameters->Add(error_param); |
7163 ParamDesc stack_trace_param; | 7015 ParamDesc stack_trace_param; |
7164 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); | 7016 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); |
7165 stack_trace_param.default_value = &Object::null_instance(); | 7017 stack_trace_param.default_value = &Object::null_instance(); |
7166 stack_trace_param.type = &Object::dynamic_type(); | 7018 stack_trace_param.type = &Object::dynamic_type(); |
7167 params->parameters->Add(stack_trace_param); | 7019 params->parameters->Add(stack_trace_param); |
7168 params->has_optional_positional_parameters = true; | 7020 params->has_optional_positional_parameters = true; |
7169 params->num_optional_parameters += 3; | 7021 params->num_optional_parameters += 3; |
7170 } | 7022 } |
7171 | 7023 |
7172 | |
7173 RawFunction* Parser::OpenAsyncFunction(TokenPosition async_func_pos) { | 7024 RawFunction* Parser::OpenAsyncFunction(TokenPosition async_func_pos) { |
7174 TRACE_PARSER("OpenAsyncFunction"); | 7025 TRACE_PARSER("OpenAsyncFunction"); |
7175 AddContinuationVariables(); | 7026 AddContinuationVariables(); |
7176 AddAsyncClosureVariables(); | 7027 AddAsyncClosureVariables(); |
7177 Function& closure = Function::Handle(Z); | 7028 Function& closure = Function::Handle(Z); |
7178 bool is_new_closure = false; | 7029 bool is_new_closure = false; |
7179 | 7030 |
7180 // Check whether a function for the asynchronous function body of | 7031 // Check whether a function for the asynchronous function body of |
7181 // this async function has already been created by a previous | 7032 // this async function has already been created by a previous |
7182 // compilation of this function. | 7033 // compilation of this function. |
(...skipping 30 matching lines...) Expand all Loading... |
7213 closure.SetSignatureType(signature_type); | 7064 closure.SetSignatureType(signature_type); |
7214 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); | 7065 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); |
7215 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | 7066 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
7216 } | 7067 } |
7217 OpenFunctionBlock(closure); | 7068 OpenFunctionBlock(closure); |
7218 AddFormalParamsToScope(&closure_params, current_block_->scope); | 7069 AddFormalParamsToScope(&closure_params, current_block_->scope); |
7219 async_temp_scope_ = current_block_->scope; | 7070 async_temp_scope_ = current_block_->scope; |
7220 return closure.raw(); | 7071 return closure.raw(); |
7221 } | 7072 } |
7222 | 7073 |
7223 | |
7224 void Parser::AddContinuationVariables() { | 7074 void Parser::AddContinuationVariables() { |
7225 // Add to current block's scope: | 7075 // Add to current block's scope: |
7226 // var :await_jump_var; | 7076 // var :await_jump_var; |
7227 // var :await_ctx_var; | 7077 // var :await_ctx_var; |
7228 LocalVariable* await_jump_var = | 7078 LocalVariable* await_jump_var = |
7229 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7079 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7230 Symbols::AwaitJumpVar(), Object::dynamic_type()); | 7080 Symbols::AwaitJumpVar(), Object::dynamic_type()); |
7231 current_block_->scope->AddVariable(await_jump_var); | 7081 current_block_->scope->AddVariable(await_jump_var); |
7232 LocalVariable* await_ctx_var = | 7082 LocalVariable* await_ctx_var = |
7233 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7083 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7234 Symbols::AwaitContextVar(), Object::dynamic_type()); | 7084 Symbols::AwaitContextVar(), Object::dynamic_type()); |
7235 current_block_->scope->AddVariable(await_ctx_var); | 7085 current_block_->scope->AddVariable(await_ctx_var); |
7236 } | 7086 } |
7237 | 7087 |
7238 | |
7239 void Parser::AddAsyncClosureVariables() { | 7088 void Parser::AddAsyncClosureVariables() { |
7240 // Add to current block's scope: | 7089 // Add to current block's scope: |
7241 // var :async_op; | 7090 // var :async_op; |
7242 // var :async_then_callback; | 7091 // var :async_then_callback; |
7243 // var :async_catch_error_callback; | 7092 // var :async_catch_error_callback; |
7244 // var :async_completer; | 7093 // var :async_completer; |
7245 // var :async_stack_trace; | 7094 // var :async_stack_trace; |
7246 LocalVariable* async_op_var = | 7095 LocalVariable* async_op_var = |
7247 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7096 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7248 Symbols::AsyncOperation(), Object::dynamic_type()); | 7097 Symbols::AsyncOperation(), Object::dynamic_type()); |
7249 current_block_->scope->AddVariable(async_op_var); | 7098 current_block_->scope->AddVariable(async_op_var); |
7250 LocalVariable* async_then_callback_var = new (Z) | 7099 LocalVariable* async_then_callback_var = new (Z) |
7251 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7100 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7252 Symbols::AsyncThenCallback(), Object::dynamic_type()); | 7101 Symbols::AsyncThenCallback(), Object::dynamic_type()); |
7253 current_block_->scope->AddVariable(async_then_callback_var); | 7102 current_block_->scope->AddVariable(async_then_callback_var); |
7254 LocalVariable* async_catch_error_callback_var = new (Z) | 7103 LocalVariable* async_catch_error_callback_var = new (Z) |
7255 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7104 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7256 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); | 7105 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); |
7257 current_block_->scope->AddVariable(async_catch_error_callback_var); | 7106 current_block_->scope->AddVariable(async_catch_error_callback_var); |
7258 LocalVariable* async_completer = | 7107 LocalVariable* async_completer = |
7259 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7108 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7260 Symbols::AsyncCompleter(), Object::dynamic_type()); | 7109 Symbols::AsyncCompleter(), Object::dynamic_type()); |
7261 current_block_->scope->AddVariable(async_completer); | 7110 current_block_->scope->AddVariable(async_completer); |
7262 LocalVariable* async_stack_trace = new (Z) | 7111 LocalVariable* async_stack_trace = new (Z) |
7263 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7112 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7264 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); | 7113 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); |
7265 current_block_->scope->AddVariable(async_stack_trace); | 7114 current_block_->scope->AddVariable(async_stack_trace); |
7266 } | 7115 } |
7267 | 7116 |
7268 | |
7269 void Parser::AddAsyncGeneratorVariables() { | 7117 void Parser::AddAsyncGeneratorVariables() { |
7270 // Add to current block's scope: | 7118 // Add to current block's scope: |
7271 // var :controller; | 7119 // var :controller; |
7272 // The :controller variable is used by the async generator closure to | 7120 // The :controller variable is used by the async generator closure to |
7273 // store the StreamController object to which the yielded expressions | 7121 // store the StreamController object to which the yielded expressions |
7274 // are added. | 7122 // are added. |
7275 // var :async_op; | 7123 // var :async_op; |
7276 // var :async_then_callback; | 7124 // var :async_then_callback; |
7277 // var :async_catch_error_callback; | 7125 // var :async_catch_error_callback; |
7278 // var :async_stack_trace; | 7126 // var :async_stack_trace; |
(...skipping 19 matching lines...) Expand all Loading... |
7298 LocalVariable* async_stack_trace = new (Z) | 7146 LocalVariable* async_stack_trace = new (Z) |
7299 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7147 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7300 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); | 7148 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); |
7301 current_block_->scope->AddVariable(async_stack_trace); | 7149 current_block_->scope->AddVariable(async_stack_trace); |
7302 LocalVariable* controller_stream = new (Z) | 7150 LocalVariable* controller_stream = new (Z) |
7303 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7151 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7304 Symbols::ControllerStream(), Object::dynamic_type()); | 7152 Symbols::ControllerStream(), Object::dynamic_type()); |
7305 current_block_->scope->AddVariable(controller_stream); | 7153 current_block_->scope->AddVariable(controller_stream); |
7306 } | 7154 } |
7307 | 7155 |
7308 | |
7309 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { | 7156 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { |
7310 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 7157 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
7311 AddContinuationVariables(); | 7158 AddContinuationVariables(); |
7312 AddAsyncGeneratorVariables(); | 7159 AddAsyncGeneratorVariables(); |
7313 | 7160 |
7314 Function& closure = Function::Handle(Z); | 7161 Function& closure = Function::Handle(Z); |
7315 bool is_new_closure = false; | 7162 bool is_new_closure = false; |
7316 | 7163 |
7317 // Check whether a function for the asynchronous function body of | 7164 // Check whether a function for the asynchronous function body of |
7318 // this async generator has already been created by a previous | 7165 // this async generator has already been created by a previous |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7352 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); | 7199 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); |
7353 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | 7200 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
7354 } | 7201 } |
7355 | 7202 |
7356 OpenFunctionBlock(closure); | 7203 OpenFunctionBlock(closure); |
7357 AddFormalParamsToScope(&closure_params, current_block_->scope); | 7204 AddFormalParamsToScope(&closure_params, current_block_->scope); |
7358 async_temp_scope_ = current_block_->scope; | 7205 async_temp_scope_ = current_block_->scope; |
7359 return closure.raw(); | 7206 return closure.raw(); |
7360 } | 7207 } |
7361 | 7208 |
7362 | |
7363 // Generate the Ast nodes for the implicit code of the async* function. | 7209 // Generate the Ast nodes for the implicit code of the async* function. |
7364 // | 7210 // |
7365 // f(...) async* { | 7211 // f(...) async* { |
7366 // var :controller; | 7212 // var :controller; |
7367 // var :await_jump_var = -1; | 7213 // var :await_jump_var = -1; |
7368 // var :await_context_var; | 7214 // var :await_context_var; |
7369 // f_async_body() { | 7215 // f_async_body() { |
7370 // ... source code of f ... | 7216 // ... source code of f ... |
7371 // } | 7217 // } |
7372 // var :async_op = f_async_body; | 7218 // var :async_op = f_async_body; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7422 // :await_jump_var = -1; | 7268 // :await_jump_var = -1; |
7423 LocalVariable* jump_var = | 7269 LocalVariable* jump_var = |
7424 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 7270 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
7425 LiteralNode* init_value = new (Z) | 7271 LiteralNode* init_value = new (Z) |
7426 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1))); | 7272 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1))); |
7427 current_block_->statements->Add( | 7273 current_block_->statements->Add( |
7428 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); | 7274 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); |
7429 | 7275 |
7430 TokenPosition token_pos = TokenPosition::kNoSource; | 7276 TokenPosition token_pos = TokenPosition::kNoSource; |
7431 | 7277 |
7432 | |
7433 // Add to AST: | 7278 // Add to AST: |
7434 // :async_op = <closure>; (containing the original body) | 7279 // :async_op = <closure>; (containing the original body) |
7435 LocalVariable* async_op_var = | 7280 LocalVariable* async_op_var = |
7436 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); | 7281 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
7437 ClosureNode* closure_obj = new (Z) ClosureNode( | 7282 ClosureNode* closure_obj = new (Z) ClosureNode( |
7438 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); | 7283 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); |
7439 StoreLocalNode* store_async_op = new (Z) | 7284 StoreLocalNode* store_async_op = new (Z) |
7440 StoreLocalNode(TokenPosition::kNoSource, async_op_var, closure_obj); | 7285 StoreLocalNode(TokenPosition::kNoSource, async_op_var, closure_obj); |
7441 | 7286 |
7442 current_block_->statements->Add(store_async_op); | 7287 current_block_->statements->Add(store_async_op); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7537 current_block_->statements->Add(store_controller_stream); | 7382 current_block_->statements->Add(store_controller_stream); |
7538 | 7383 |
7539 // return :controller.stream; | 7384 // return :controller.stream; |
7540 ReturnNode* return_node = new (Z) ReturnNode( | 7385 ReturnNode* return_node = new (Z) ReturnNode( |
7541 TokenPosition::kNoSource, | 7386 TokenPosition::kNoSource, |
7542 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_stream_var)); | 7387 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_stream_var)); |
7543 current_block_->statements->Add(return_node); | 7388 current_block_->statements->Add(return_node); |
7544 return CloseBlock(); | 7389 return CloseBlock(); |
7545 } | 7390 } |
7546 | 7391 |
7547 | |
7548 void Parser::OpenAsyncGeneratorClosure() { | 7392 void Parser::OpenAsyncGeneratorClosure() { |
7549 async_temp_scope_ = current_block_->scope; | 7393 async_temp_scope_ = current_block_->scope; |
7550 OpenAsyncTryBlock(); | 7394 OpenAsyncTryBlock(); |
7551 } | 7395 } |
7552 | 7396 |
7553 | |
7554 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { | 7397 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { |
7555 // We need a temporary expression to store intermediate return values. | 7398 // We need a temporary expression to store intermediate return values. |
7556 parsed_function()->EnsureExpressionTemp(); | 7399 parsed_function()->EnsureExpressionTemp(); |
7557 | 7400 |
7558 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); | 7401 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); |
7559 ASSERT(new_body != NULL); | 7402 ASSERT(new_body != NULL); |
7560 ASSERT(new_body->scope() != NULL); | 7403 ASSERT(new_body->scope() != NULL); |
7561 return new_body; | 7404 return new_body; |
7562 } | 7405 } |
7563 | 7406 |
7564 | |
7565 // Add a return node to the sequence if necessary. | 7407 // Add a return node to the sequence if necessary. |
7566 void Parser::EnsureHasReturnStatement(SequenceNode* seq, | 7408 void Parser::EnsureHasReturnStatement(SequenceNode* seq, |
7567 TokenPosition return_pos) { | 7409 TokenPosition return_pos) { |
7568 if ((seq->length() == 0) || !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { | 7410 if ((seq->length() == 0) || !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { |
7569 const Function& func = innermost_function(); | 7411 const Function& func = innermost_function(); |
7570 // The implicit return value of synchronous generator closures is false, | 7412 // The implicit return value of synchronous generator closures is false, |
7571 // to indicate that there are no more elements in the iterable. | 7413 // to indicate that there are no more elements in the iterable. |
7572 // In other cases the implicit return value is null. | 7414 // In other cases the implicit return value is null. |
7573 AstNode* return_value = | 7415 AstNode* return_value = |
7574 func.IsSyncGenClosure() | 7416 func.IsSyncGenClosure() |
7575 ? new LiteralNode(return_pos, Bool::False()) | 7417 ? new LiteralNode(return_pos, Bool::False()) |
7576 : new LiteralNode(return_pos, Instance::ZoneHandle()); | 7418 : new LiteralNode(return_pos, Instance::ZoneHandle()); |
7577 seq->Add(new ReturnNode(return_pos, return_value)); | 7419 seq->Add(new ReturnNode(return_pos, return_value)); |
7578 } | 7420 } |
7579 } | 7421 } |
7580 | 7422 |
7581 | |
7582 SequenceNode* Parser::CloseBlock() { | 7423 SequenceNode* Parser::CloseBlock() { |
7583 SequenceNode* statements = current_block_->statements; | 7424 SequenceNode* statements = current_block_->statements; |
7584 if (current_block_->scope != NULL) { | 7425 if (current_block_->scope != NULL) { |
7585 // Record the begin and end token index of the scope. | 7426 // Record the begin and end token index of the scope. |
7586 ASSERT(statements != NULL); | 7427 ASSERT(statements != NULL); |
7587 current_block_->scope->set_begin_token_pos(statements->token_pos()); | 7428 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
7588 current_block_->scope->set_end_token_pos(TokenPos()); | 7429 current_block_->scope->set_end_token_pos(TokenPos()); |
7589 } | 7430 } |
7590 current_block_ = current_block_->parent; | 7431 current_block_ = current_block_->parent; |
7591 return statements; | 7432 return statements; |
7592 } | 7433 } |
7593 | 7434 |
7594 | |
7595 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, | 7435 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, |
7596 SequenceNode* closure_body) { | 7436 SequenceNode* closure_body) { |
7597 TRACE_PARSER("CloseAsyncFunction"); | 7437 TRACE_PARSER("CloseAsyncFunction"); |
7598 ASSERT(!closure.IsNull()); | 7438 ASSERT(!closure.IsNull()); |
7599 ASSERT(closure_body != NULL); | 7439 ASSERT(closure_body != NULL); |
7600 | 7440 |
7601 // Explicitly reference variables of the async function from the | 7441 // Explicitly reference variables of the async function from the |
7602 // closure body in order to mark them as captured. | 7442 // closure body in order to mark them as captured. |
7603 LocalVariable* existing_var = | 7443 LocalVariable* existing_var = |
7604 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 7444 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7737 // return :async_completer.future; | 7577 // return :async_completer.future; |
7738 ReturnNode* return_node = new (Z) ReturnNode( | 7578 ReturnNode* return_node = new (Z) ReturnNode( |
7739 token_pos, | 7579 token_pos, |
7740 new (Z) InstanceGetterNode( | 7580 new (Z) InstanceGetterNode( |
7741 token_pos, new (Z) LoadLocalNode(token_pos, async_completer), | 7581 token_pos, new (Z) LoadLocalNode(token_pos, async_completer), |
7742 Symbols::CompleterFuture())); | 7582 Symbols::CompleterFuture())); |
7743 current_block_->statements->Add(return_node); | 7583 current_block_->statements->Add(return_node); |
7744 return CloseBlock(); | 7584 return CloseBlock(); |
7745 } | 7585 } |
7746 | 7586 |
7747 | |
7748 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body, | 7587 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body, |
7749 TokenPosition func_end_pos) { | 7588 TokenPosition func_end_pos) { |
7750 // We need a temporary expression to store intermediate return values. | 7589 // We need a temporary expression to store intermediate return values. |
7751 parsed_function()->EnsureExpressionTemp(); | 7590 parsed_function()->EnsureExpressionTemp(); |
7752 | 7591 |
7753 SequenceNode* new_body = CloseAsyncTryBlock(body, func_end_pos); | 7592 SequenceNode* new_body = CloseAsyncTryBlock(body, func_end_pos); |
7754 ASSERT(new_body != NULL); | 7593 ASSERT(new_body != NULL); |
7755 ASSERT(new_body->scope() != NULL); | 7594 ASSERT(new_body->scope() != NULL); |
7756 return new_body; | 7595 return new_body; |
7757 } | 7596 } |
7758 | 7597 |
7759 | |
7760 // Set up default values for all optional parameters to the function. | 7598 // Set up default values for all optional parameters to the function. |
7761 void Parser::SetupDefaultsForOptionalParams(const ParamList& params) { | 7599 void Parser::SetupDefaultsForOptionalParams(const ParamList& params) { |
7762 if ((current_function().raw() == innermost_function().raw()) && | 7600 if ((current_function().raw() == innermost_function().raw()) && |
7763 (params.num_optional_parameters > 0)) { | 7601 (params.num_optional_parameters > 0)) { |
7764 ZoneGrowableArray<const Instance*>* default_values = | 7602 ZoneGrowableArray<const Instance*>* default_values = |
7765 new ZoneGrowableArray<const Instance*>(zone(), | 7603 new ZoneGrowableArray<const Instance*>(zone(), |
7766 params.num_optional_parameters); | 7604 params.num_optional_parameters); |
7767 // Build array of default parameter values. | 7605 // Build array of default parameter values. |
7768 const ZoneGrowableArray<ParamDesc>& parameters = *params.parameters; | 7606 const ZoneGrowableArray<ParamDesc>& parameters = *params.parameters; |
7769 const int first_opt_param_offset = params.num_fixed_parameters; | 7607 const int first_opt_param_offset = params.num_fixed_parameters; |
7770 for (int i = 0; i < params.num_optional_parameters; i++) { | 7608 for (int i = 0; i < params.num_optional_parameters; i++) { |
7771 const Instance* default_value = | 7609 const Instance* default_value = |
7772 parameters[i + first_opt_param_offset].default_value; | 7610 parameters[i + first_opt_param_offset].default_value; |
7773 default_values->Add(default_value); | 7611 default_values->Add(default_value); |
7774 } | 7612 } |
7775 parsed_function()->set_default_parameter_values(default_values); | 7613 parsed_function()->set_default_parameter_values(default_values); |
7776 } | 7614 } |
7777 } | 7615 } |
7778 | 7616 |
7779 | |
7780 void Parser::FinalizeFormalParameterTypes(const ParamList* params) { | 7617 void Parser::FinalizeFormalParameterTypes(const ParamList* params) { |
7781 ASSERT((params != NULL) && (params->parameters != NULL)); | 7618 ASSERT((params != NULL) && (params->parameters != NULL)); |
7782 const int num_parameters = params->parameters->length(); | 7619 const int num_parameters = params->parameters->length(); |
7783 AbstractType& type = AbstractType::Handle(Z); | 7620 AbstractType& type = AbstractType::Handle(Z); |
7784 for (int i = 0; i < num_parameters; i++) { | 7621 for (int i = 0; i < num_parameters; i++) { |
7785 ParamDesc& param_desc = (*params->parameters)[i]; | 7622 ParamDesc& param_desc = (*params->parameters)[i]; |
7786 type = param_desc.type->raw(); | 7623 type = param_desc.type->raw(); |
7787 ResolveType(&type); | 7624 ResolveType(&type); |
7788 type = CanonicalizeType(type); | 7625 type = CanonicalizeType(type); |
7789 if (type.raw() != param_desc.type->raw()) { | 7626 if (type.raw() != param_desc.type->raw()) { |
7790 param_desc.type = &AbstractType::ZoneHandle(Z, type.raw()); | 7627 param_desc.type = &AbstractType::ZoneHandle(Z, type.raw()); |
7791 } | 7628 } |
7792 } | 7629 } |
7793 } | 7630 } |
7794 | 7631 |
7795 | |
7796 // Populate the parameter type array and parameter name array of the function | 7632 // Populate the parameter type array and parameter name array of the function |
7797 // with the formal parameter types and names. | 7633 // with the formal parameter types and names. |
7798 void Parser::AddFormalParamsToFunction(const ParamList* params, | 7634 void Parser::AddFormalParamsToFunction(const ParamList* params, |
7799 const Function& func) { | 7635 const Function& func) { |
7800 ASSERT((params != NULL) && (params->parameters != NULL)); | 7636 ASSERT((params != NULL) && (params->parameters != NULL)); |
7801 ASSERT((params->num_optional_parameters > 0) == | 7637 ASSERT((params->num_optional_parameters > 0) == |
7802 (params->has_optional_positional_parameters || | 7638 (params->has_optional_positional_parameters || |
7803 params->has_optional_named_parameters)); | 7639 params->has_optional_named_parameters)); |
7804 if (!Utils::IsInt(16, params->num_fixed_parameters) || | 7640 if (!Utils::IsInt(16, params->num_fixed_parameters) || |
7805 !Utils::IsInt(16, params->num_optional_parameters)) { | 7641 !Utils::IsInt(16, params->num_optional_parameters)) { |
(...skipping 25 matching lines...) Expand all Loading... |
7831 if (param_desc.is_covariant) { | 7667 if (param_desc.is_covariant) { |
7832 if (!func.IsDynamicFunction(true)) { | 7668 if (!func.IsDynamicFunction(true)) { |
7833 ReportError(param_desc.name_pos, | 7669 ReportError(param_desc.name_pos, |
7834 "only instance functions may have " | 7670 "only instance functions may have " |
7835 "covariant parameters"); | 7671 "covariant parameters"); |
7836 } | 7672 } |
7837 } | 7673 } |
7838 } | 7674 } |
7839 } | 7675 } |
7840 | 7676 |
7841 | |
7842 // Populate local scope with the formal parameters. | 7677 // Populate local scope with the formal parameters. |
7843 void Parser::AddFormalParamsToScope(const ParamList* params, | 7678 void Parser::AddFormalParamsToScope(const ParamList* params, |
7844 LocalScope* scope) { | 7679 LocalScope* scope) { |
7845 ASSERT((params != NULL) && (params->parameters != NULL)); | 7680 ASSERT((params != NULL) && (params->parameters != NULL)); |
7846 ASSERT(scope != NULL); | 7681 ASSERT(scope != NULL); |
7847 const int num_parameters = params->parameters->length(); | 7682 const int num_parameters = params->parameters->length(); |
7848 for (int i = 0; i < num_parameters; i++) { | 7683 for (int i = 0; i < num_parameters; i++) { |
7849 ParamDesc& param_desc = (*params->parameters)[i]; | 7684 ParamDesc& param_desc = (*params->parameters)[i]; |
7850 const String* name = param_desc.name; | 7685 const String* name = param_desc.name; |
7851 LocalVariable* parameter = new (Z) LocalVariable( | 7686 LocalVariable* parameter = new (Z) LocalVariable( |
7852 param_desc.name_pos, param_desc.name_pos, *name, *param_desc.type); | 7687 param_desc.name_pos, param_desc.name_pos, *name, *param_desc.type); |
7853 if (!scope->InsertParameterAt(i, parameter)) { | 7688 if (!scope->InsertParameterAt(i, parameter)) { |
7854 ReportError(param_desc.name_pos, "name '%s' already exists in scope", | 7689 ReportError(param_desc.name_pos, "name '%s' already exists in scope", |
7855 param_desc.name->ToCString()); | 7690 param_desc.name->ToCString()); |
7856 } | 7691 } |
7857 param_desc.var = parameter; | 7692 param_desc.var = parameter; |
7858 if (param_desc.is_final) { | 7693 if (param_desc.is_final) { |
7859 parameter->set_is_final(); | 7694 parameter->set_is_final(); |
7860 } | 7695 } |
7861 if (FLAG_initializing_formal_access) { | 7696 if (FLAG_initializing_formal_access) { |
7862 // Field initializer parameters are implicitly final. | 7697 // Field initializer parameters are implicitly final. |
7863 ASSERT(!param_desc.is_field_initializer || param_desc.is_final); | 7698 ASSERT(!param_desc.is_field_initializer || param_desc.is_final); |
7864 } else if (param_desc.is_field_initializer) { | 7699 } else if (param_desc.is_field_initializer) { |
7865 parameter->set_invisible(true); | 7700 parameter->set_invisible(true); |
7866 } | 7701 } |
7867 } | 7702 } |
7868 } | 7703 } |
7869 | 7704 |
7870 | |
7871 // Builds ReturnNode/NativeBodyNode for a native function. | 7705 // Builds ReturnNode/NativeBodyNode for a native function. |
7872 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 7706 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
7873 const Function& func) { | 7707 const Function& func) { |
7874 ASSERT(func.is_native()); | 7708 ASSERT(func.is_native()); |
7875 ASSERT(func.NumParameters() == params->parameters->length()); | 7709 ASSERT(func.NumParameters() == params->parameters->length()); |
7876 TRACE_PARSER("ParseNativeFunctionBlock"); | 7710 TRACE_PARSER("ParseNativeFunctionBlock"); |
7877 | 7711 |
7878 // Parse the function name out. | 7712 // Parse the function name out. |
7879 const String& native_name = ParseNativeDeclaration(); | 7713 const String& native_name = ParseNativeDeclaration(); |
7880 | 7714 |
7881 // Now add the NativeBodyNode and return statement. | 7715 // Now add the NativeBodyNode and return statement. |
7882 current_block_->statements->Add(new (Z) ReturnNode( | 7716 current_block_->statements->Add(new (Z) ReturnNode( |
7883 TokenPos(), | 7717 TokenPos(), |
7884 new (Z) NativeBodyNode(TokenPos(), Function::ZoneHandle(Z, func.raw()), | 7718 new (Z) NativeBodyNode(TokenPos(), Function::ZoneHandle(Z, func.raw()), |
7885 native_name, current_block_->scope, | 7719 native_name, current_block_->scope, |
7886 FLAG_link_natives_lazily))); | 7720 FLAG_link_natives_lazily))); |
7887 } | 7721 } |
7888 | 7722 |
7889 | |
7890 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 7723 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
7891 ASSERT(!current_function().is_static()); | 7724 ASSERT(!current_function().is_static()); |
7892 return from_scope->LookupVariable(Symbols::This(), test_only); | 7725 return from_scope->LookupVariable(Symbols::This(), test_only); |
7893 } | 7726 } |
7894 | 7727 |
7895 | |
7896 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, | 7728 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, |
7897 bool test_only) { | 7729 bool test_only) { |
7898 ASSERT(current_function().IsInFactoryScope()); | 7730 ASSERT(current_function().IsInFactoryScope()); |
7899 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), | 7731 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), |
7900 test_only); | 7732 test_only); |
7901 } | 7733 } |
7902 | 7734 |
7903 | |
7904 void Parser::CaptureInstantiator() { | 7735 void Parser::CaptureInstantiator() { |
7905 ASSERT(FunctionLevel() > 0); | 7736 ASSERT(FunctionLevel() > 0); |
7906 const String* variable_name = current_function().IsInFactoryScope() | 7737 const String* variable_name = current_function().IsInFactoryScope() |
7907 ? &Symbols::TypeArgumentsParameter() | 7738 ? &Symbols::TypeArgumentsParameter() |
7908 : &Symbols::This(); | 7739 : &Symbols::This(); |
7909 current_block_->scope->CaptureVariable( | 7740 current_block_->scope->CaptureVariable( |
7910 current_block_->scope->LookupVariable(*variable_name, true)); | 7741 current_block_->scope->LookupVariable(*variable_name, true)); |
7911 } | 7742 } |
7912 | 7743 |
7913 | |
7914 void Parser::CaptureFunctionTypeArguments() { | 7744 void Parser::CaptureFunctionTypeArguments() { |
7915 ASSERT(InGenericFunctionScope()); | 7745 ASSERT(InGenericFunctionScope()); |
7916 ASSERT(FunctionLevel() > 0); | 7746 ASSERT(FunctionLevel() > 0); |
7917 if (!FLAG_reify_generic_functions) { | 7747 if (!FLAG_reify_generic_functions) { |
7918 return; | 7748 return; |
7919 } | 7749 } |
7920 const String* variable_name = &Symbols::FunctionTypeArgumentsVar(); | 7750 const String* variable_name = &Symbols::FunctionTypeArgumentsVar(); |
7921 current_block_->scope->CaptureVariable( | 7751 current_block_->scope->CaptureVariable( |
7922 current_block_->scope->LookupVariable(*variable_name, true)); | 7752 current_block_->scope->LookupVariable(*variable_name, true)); |
7923 } | 7753 } |
7924 | 7754 |
7925 | |
7926 void Parser::CaptureAllInstantiators() { | 7755 void Parser::CaptureAllInstantiators() { |
7927 if (IsInstantiatorRequired()) { | 7756 if (IsInstantiatorRequired()) { |
7928 CaptureInstantiator(); | 7757 CaptureInstantiator(); |
7929 } | 7758 } |
7930 if (innermost_function().HasGenericParent()) { | 7759 if (innermost_function().HasGenericParent()) { |
7931 CaptureFunctionTypeArguments(); | 7760 CaptureFunctionTypeArguments(); |
7932 } | 7761 } |
7933 } | 7762 } |
7934 | 7763 |
7935 | |
7936 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { | 7764 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { |
7937 // A nested function may access 'this', referring to the receiver of the | 7765 // A nested function may access 'this', referring to the receiver of the |
7938 // outermost enclosing function. | 7766 // outermost enclosing function. |
7939 const bool kTestOnly = false; | 7767 const bool kTestOnly = false; |
7940 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7768 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
7941 if (receiver == NULL) { | 7769 if (receiver == NULL) { |
7942 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7770 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
7943 } | 7771 } |
7944 return new (Z) LoadLocalNode(TokenPos(), receiver); | 7772 return new (Z) LoadLocalNode(TokenPos(), receiver); |
7945 } | 7773 } |
7946 | 7774 |
7947 | |
7948 InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos, | 7775 InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos, |
7949 AstNode* object, | 7776 AstNode* object, |
7950 const String& name) { | 7777 const String& name) { |
7951 return new (Z) InstanceGetterNode(token_pos, object, name); | 7778 return new (Z) InstanceGetterNode(token_pos, object, name); |
7952 } | 7779 } |
7953 | 7780 |
7954 | |
7955 // Returns ast nodes of the variable initialization. | 7781 // Returns ast nodes of the variable initialization. |
7956 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 7782 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
7957 bool is_final, | 7783 bool is_final, |
7958 bool is_const, | 7784 bool is_const, |
7959 SequenceNode** await_preamble) { | 7785 SequenceNode** await_preamble) { |
7960 TRACE_PARSER("ParseVariableDeclaration"); | 7786 TRACE_PARSER("ParseVariableDeclaration"); |
7961 ASSERT(IsIdentifier()); | 7787 ASSERT(IsIdentifier()); |
7962 const TokenPosition ident_pos = TokenPos(); | 7788 const TokenPosition ident_pos = TokenPos(); |
7963 const String& ident = *CurrentLiteral(); | 7789 const String& ident = *CurrentLiteral(); |
7964 ConsumeToken(); // Variable identifier. | 7790 ConsumeToken(); // Variable identifier. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8015 ASSERT(existing_var->owner() == current_block_->scope); | 7841 ASSERT(existing_var->owner() == current_block_->scope); |
8016 ReportError(ident_pos, "identifier '%s' already defined", | 7842 ReportError(ident_pos, "identifier '%s' already defined", |
8017 variable->name().ToCString()); | 7843 variable->name().ToCString()); |
8018 } | 7844 } |
8019 if (is_final || is_const) { | 7845 if (is_final || is_const) { |
8020 variable->set_is_final(); | 7846 variable->set_is_final(); |
8021 } | 7847 } |
8022 return initialization; | 7848 return initialization; |
8023 } | 7849 } |
8024 | 7850 |
8025 | |
8026 // Parses ('var' | 'final' [type] | 'const' [type] | type). | 7851 // Parses ('var' | 'final' [type] | 'const' [type] | type). |
8027 // The presence of 'final' or 'const' must be detected and remembered | 7852 // The presence of 'final' or 'const' must be detected and remembered |
8028 // before the call. If a type is parsed, it may be resolved and finalized | 7853 // before the call. If a type is parsed, it may be resolved and finalized |
8029 // according to the given type finalization mode. | 7854 // according to the given type finalization mode. |
8030 RawAbstractType* Parser::ParseConstFinalVarOrType( | 7855 RawAbstractType* Parser::ParseConstFinalVarOrType( |
8031 ClassFinalizer::FinalizationKind finalization) { | 7856 ClassFinalizer::FinalizationKind finalization) { |
8032 TRACE_PARSER("ParseConstFinalVarOrType"); | 7857 TRACE_PARSER("ParseConstFinalVarOrType"); |
8033 if (CurrentToken() == Token::kVAR) { | 7858 if (CurrentToken() == Token::kVAR) { |
8034 ConsumeToken(); | 7859 ConsumeToken(); |
8035 return Type::DynamicType(); | 7860 return Type::DynamicType(); |
(...skipping 20 matching lines...) Expand all Loading... |
8056 if ((follower != Token::kLT) && // Parameterized type. | 7881 if ((follower != Token::kLT) && // Parameterized type. |
8057 (follower != Token::kPERIOD) && // Qualified class name of type. | 7882 (follower != Token::kPERIOD) && // Qualified class name of type. |
8058 !Token::IsIdentifier(follower) && // Variable name following a type. | 7883 !Token::IsIdentifier(follower) && // Variable name following a type. |
8059 (follower != Token::kTHIS)) { // Field parameter following a type. | 7884 (follower != Token::kTHIS)) { // Field parameter following a type. |
8060 return Type::DynamicType(); | 7885 return Type::DynamicType(); |
8061 } | 7886 } |
8062 } | 7887 } |
8063 return ParseTypeOrFunctionType(false, finalization); | 7888 return ParseTypeOrFunctionType(false, finalization); |
8064 } | 7889 } |
8065 | 7890 |
8066 | |
8067 // Returns ast nodes of the variable initialization. Variables without an | 7891 // Returns ast nodes of the variable initialization. Variables without an |
8068 // explicit initializer are initialized to null. If several variables are | 7892 // explicit initializer are initialized to null. If several variables are |
8069 // declared, the individual initializers are collected in a sequence node. | 7893 // declared, the individual initializers are collected in a sequence node. |
8070 AstNode* Parser::ParseVariableDeclarationList() { | 7894 AstNode* Parser::ParseVariableDeclarationList() { |
8071 TRACE_PARSER("ParseVariableDeclarationList"); | 7895 TRACE_PARSER("ParseVariableDeclarationList"); |
8072 SkipMetadata(); | 7896 SkipMetadata(); |
8073 bool is_final = (CurrentToken() == Token::kFINAL); | 7897 bool is_final = (CurrentToken() == Token::kFINAL); |
8074 bool is_const = (CurrentToken() == Token::kCONST); | 7898 bool is_const = (CurrentToken() == Token::kCONST); |
8075 const AbstractType& type = AbstractType::ZoneHandle( | 7899 const AbstractType& type = AbstractType::ZoneHandle( |
8076 Z, | 7900 Z, |
(...skipping 25 matching lines...) Expand all Loading... |
8102 ParseVariableDeclaration(type, is_final, is_const, &preamble); | 7926 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
8103 if (preamble != NULL) { | 7927 if (preamble != NULL) { |
8104 sequence->Add(preamble); | 7928 sequence->Add(preamble); |
8105 } | 7929 } |
8106 sequence->Add(declaration); | 7930 sequence->Add(declaration); |
8107 initializers = sequence; | 7931 initializers = sequence; |
8108 } | 7932 } |
8109 return initializers; | 7933 return initializers; |
8110 } | 7934 } |
8111 | 7935 |
8112 | |
8113 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 7936 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
8114 TRACE_PARSER("ParseFunctionStatement"); | 7937 TRACE_PARSER("ParseFunctionStatement"); |
8115 AbstractType& result_type = AbstractType::Handle(Z, Type::DynamicType()); | 7938 AbstractType& result_type = AbstractType::Handle(Z, Type::DynamicType()); |
8116 const String* function_name = NULL; | 7939 const String* function_name = NULL; |
8117 const TokenPosition function_pos = TokenPos(); | 7940 const TokenPosition function_pos = TokenPos(); |
8118 TokenPosition function_name_pos = TokenPosition::kNoSource; | 7941 TokenPosition function_name_pos = TokenPosition::kNoSource; |
8119 TokenPosition metadata_pos = TokenPosition::kNoSource; | 7942 TokenPosition metadata_pos = TokenPosition::kNoSource; |
8120 if (is_literal) { | 7943 if (is_literal) { |
8121 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT); | 7944 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT); |
8122 function_name = &Symbols::AnonymousClosure(); | 7945 function_name = &Symbols::AnonymousClosure(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8309 // The local scope of the parsed function can be pruned, since contained | 8132 // The local scope of the parsed function can be pruned, since contained |
8310 // variables are not relevant for the compilation of the enclosing function. | 8133 // variables are not relevant for the compilation of the enclosing function. |
8311 // This pruning is done by omitting to hook the local scope in its parent | 8134 // This pruning is done by omitting to hook the local scope in its parent |
8312 // scope in the constructor of LocalScope. | 8135 // scope in the constructor of LocalScope. |
8313 AstNode* closure = | 8136 AstNode* closure = |
8314 new (Z) ClosureNode(function_pos, function, NULL, | 8137 new (Z) ClosureNode(function_pos, function, NULL, |
8315 statements != NULL ? statements->scope() : NULL); | 8138 statements != NULL ? statements->scope() : NULL); |
8316 | 8139 |
8317 ASSERT(innermost_function_.raw() == function.raw()); | 8140 ASSERT(innermost_function_.raw() == function.raw()); |
8318 innermost_function_ = function.parent_function(); | 8141 innermost_function_ = function.parent_function(); |
8319 return is_literal ? closure : new (Z) StoreLocalNode( | 8142 return is_literal |
8320 function_pos, function_variable, closure); | 8143 ? closure |
| 8144 : new (Z) StoreLocalNode(function_pos, function_variable, closure); |
8321 } | 8145 } |
8322 | 8146 |
8323 | |
8324 // Returns true if the current and next tokens can be parsed as type | 8147 // Returns true if the current and next tokens can be parsed as type |
8325 // parameters. Current token position is not saved and restored. | 8148 // parameters. Current token position is not saved and restored. |
8326 bool Parser::TryParseTypeParameters() { | 8149 bool Parser::TryParseTypeParameters() { |
8327 ASSERT(CurrentToken() == Token::kLT); | 8150 ASSERT(CurrentToken() == Token::kLT); |
8328 int nesting_level = 0; | 8151 int nesting_level = 0; |
8329 do { | 8152 do { |
8330 Token::Kind ct = CurrentToken(); | 8153 Token::Kind ct = CurrentToken(); |
8331 if (ct == Token::kLT) { | 8154 if (ct == Token::kLT) { |
8332 nesting_level++; | 8155 nesting_level++; |
8333 } else if (ct == Token::kGT) { | 8156 } else if (ct == Token::kGT) { |
(...skipping 12 matching lines...) Expand all Loading... |
8346 return false; | 8169 return false; |
8347 } | 8170 } |
8348 ConsumeToken(); | 8171 ConsumeToken(); |
8349 } while (nesting_level > 0); | 8172 } while (nesting_level > 0); |
8350 if (nesting_level < 0) { | 8173 if (nesting_level < 0) { |
8351 return false; | 8174 return false; |
8352 } | 8175 } |
8353 return true; | 8176 return true; |
8354 } | 8177 } |
8355 | 8178 |
8356 | |
8357 // Returns true if the next tokens can be parsed as type parameters. | 8179 // Returns true if the next tokens can be parsed as type parameters. |
8358 bool Parser::IsTypeParameters() { | 8180 bool Parser::IsTypeParameters() { |
8359 if (CurrentToken() == Token::kLT) { | 8181 if (CurrentToken() == Token::kLT) { |
8360 TokenPosScope param_pos(this); | 8182 TokenPosScope param_pos(this); |
8361 if (!TryParseTypeParameters()) { | 8183 if (!TryParseTypeParameters()) { |
8362 return false; | 8184 return false; |
8363 } | 8185 } |
8364 return true; | 8186 return true; |
8365 } | 8187 } |
8366 return false; | 8188 return false; |
8367 } | 8189 } |
8368 | 8190 |
8369 | |
8370 // Returns true if the next tokens are [ typeParameters ] '('. | 8191 // Returns true if the next tokens are [ typeParameters ] '('. |
8371 bool Parser::IsParameterPart() { | 8192 bool Parser::IsParameterPart() { |
8372 if (CurrentToken() == Token::kLPAREN) { | 8193 if (CurrentToken() == Token::kLPAREN) { |
8373 return true; | 8194 return true; |
8374 } | 8195 } |
8375 if (CurrentToken() == Token::kLT) { | 8196 if (CurrentToken() == Token::kLT) { |
8376 TokenPosScope type_arg_pos(this); | 8197 TokenPosScope type_arg_pos(this); |
8377 if (!TryParseTypeParameters()) { | 8198 if (!TryParseTypeParameters()) { |
8378 return false; | 8199 return false; |
8379 } | 8200 } |
8380 return CurrentToken() == Token::kLPAREN; | 8201 return CurrentToken() == Token::kLPAREN; |
8381 } | 8202 } |
8382 return false; | 8203 return false; |
8383 } | 8204 } |
8384 | 8205 |
8385 | |
8386 // Returns true if the current and next tokens can be parsed as type | 8206 // Returns true if the current and next tokens can be parsed as type |
8387 // arguments. Current token position is not saved and restored. | 8207 // arguments. Current token position is not saved and restored. |
8388 bool Parser::TryParseTypeArguments() { | 8208 bool Parser::TryParseTypeArguments() { |
8389 ASSERT(CurrentToken() == Token::kLT); | 8209 ASSERT(CurrentToken() == Token::kLT); |
8390 int nesting_level = 0; | 8210 int nesting_level = 0; |
8391 do { | 8211 do { |
8392 Token::Kind ct = CurrentToken(); | 8212 Token::Kind ct = CurrentToken(); |
8393 if (ct == Token::kLT) { | 8213 if (ct == Token::kLT) { |
8394 nesting_level++; | 8214 nesting_level++; |
8395 } else if (ct == Token::kGT) { | 8215 } else if (ct == Token::kGT) { |
(...skipping 17 matching lines...) Expand all Loading... |
8413 return false; | 8233 return false; |
8414 } | 8234 } |
8415 ConsumeToken(); | 8235 ConsumeToken(); |
8416 } while (nesting_level > 0); | 8236 } while (nesting_level > 0); |
8417 if (nesting_level < 0) { | 8237 if (nesting_level < 0) { |
8418 return false; | 8238 return false; |
8419 } | 8239 } |
8420 return true; | 8240 return true; |
8421 } | 8241 } |
8422 | 8242 |
8423 | |
8424 // Returns true if the next tokens are [ typeArguments ] '('. | 8243 // Returns true if the next tokens are [ typeArguments ] '('. |
8425 bool Parser::IsArgumentPart() { | 8244 bool Parser::IsArgumentPart() { |
8426 if (CurrentToken() == Token::kLPAREN) { | 8245 if (CurrentToken() == Token::kLPAREN) { |
8427 return true; | 8246 return true; |
8428 } | 8247 } |
8429 if (CurrentToken() == Token::kLT) { | 8248 if (CurrentToken() == Token::kLT) { |
8430 TokenPosScope type_arg_pos(this); | 8249 TokenPosScope type_arg_pos(this); |
8431 if (!TryParseTypeArguments()) { | 8250 if (!TryParseTypeArguments()) { |
8432 return false; | 8251 return false; |
8433 } | 8252 } |
8434 return CurrentToken() == Token::kLPAREN; | 8253 return CurrentToken() == Token::kLPAREN; |
8435 } | 8254 } |
8436 return false; | 8255 return false; |
8437 } | 8256 } |
8438 | 8257 |
8439 | |
8440 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { | 8258 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { |
8441 // Assigning null never causes a type error. | 8259 // Assigning null never causes a type error. |
8442 if (CurrentToken() == Token::kNULL) { | 8260 if (CurrentToken() == Token::kNULL) { |
8443 *value = Instance::null(); | 8261 *value = Instance::null(); |
8444 return true; | 8262 return true; |
8445 } | 8263 } |
8446 // If the type of the const field is guaranteed to be instantiated once | 8264 // If the type of the const field is guaranteed to be instantiated once |
8447 // resolved at class finalization time, and if the type of the literal is one | 8265 // resolved at class finalization time, and if the type of the literal is one |
8448 // of int, double, String, or bool, then preset the field with the value and | 8266 // of int, double, String, or bool, then preset the field with the value and |
8449 // perform the type check (in checked mode only) at finalization time. | 8267 // perform the type check (in checked mode only) at finalization time. |
(...skipping 19 matching lines...) Expand all Loading... |
8469 } else if (CurrentToken() == Token::kTRUE) { | 8287 } else if (CurrentToken() == Token::kTRUE) { |
8470 *value = Bool::True().raw(); | 8288 *value = Bool::True().raw(); |
8471 return true; | 8289 return true; |
8472 } else if (CurrentToken() == Token::kFALSE) { | 8290 } else if (CurrentToken() == Token::kFALSE) { |
8473 *value = Bool::False().raw(); | 8291 *value = Bool::False().raw(); |
8474 return true; | 8292 return true; |
8475 } | 8293 } |
8476 return false; | 8294 return false; |
8477 } | 8295 } |
8478 | 8296 |
8479 | |
8480 // Returns true if the current token is kIDENT or a pseudo-keyword. | 8297 // Returns true if the current token is kIDENT or a pseudo-keyword. |
8481 bool Parser::IsIdentifier() { | 8298 bool Parser::IsIdentifier() { |
8482 return Token::IsIdentifier(CurrentToken()) && | 8299 return Token::IsIdentifier(CurrentToken()) && |
8483 !(await_is_keyword_ && | 8300 !(await_is_keyword_ && |
8484 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || | 8301 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || |
8485 (CurrentLiteral()->raw() == Symbols::Async().raw()) || | 8302 (CurrentLiteral()->raw() == Symbols::Async().raw()) || |
8486 (CurrentLiteral()->raw() == Symbols::YieldKw().raw()))); | 8303 (CurrentLiteral()->raw() == Symbols::YieldKw().raw()))); |
8487 } | 8304 } |
8488 | 8305 |
8489 | |
8490 bool Parser::IsSymbol(const String& symbol) { | 8306 bool Parser::IsSymbol(const String& symbol) { |
8491 return (CurrentLiteral()->raw() == symbol.raw()) && | 8307 return (CurrentLiteral()->raw() == symbol.raw()) && |
8492 (CurrentToken() == Token::kIDENT); | 8308 (CurrentToken() == Token::kIDENT); |
8493 } | 8309 } |
8494 | 8310 |
8495 | |
8496 // Returns true if the current token is 'Function' followed by '<' or '('. | 8311 // Returns true if the current token is 'Function' followed by '<' or '('. |
8497 // 'Function' not followed by '<' or '(' denotes the Function class. | 8312 // 'Function' not followed by '<' or '(' denotes the Function class. |
8498 bool Parser::IsFunctionTypeSymbol() { | 8313 bool Parser::IsFunctionTypeSymbol() { |
8499 return IsSymbol(Symbols::Function()) && | 8314 return IsSymbol(Symbols::Function()) && |
8500 ((LookaheadToken(1) == Token::kLPAREN) || | 8315 ((LookaheadToken(1) == Token::kLPAREN) || |
8501 (LookaheadToken(1) == Token::kLT)); | 8316 (LookaheadToken(1) == Token::kLT)); |
8502 } | 8317 } |
8503 | 8318 |
8504 | |
8505 // Returns true if the next tokens can be parsed as a an optionally | 8319 // Returns true if the next tokens can be parsed as a an optionally |
8506 // qualified identifier: [ident '.'] ident. | 8320 // qualified identifier: [ident '.'] ident. |
8507 // Current token position is not restored. | 8321 // Current token position is not restored. |
8508 bool Parser::TryParseQualIdent() { | 8322 bool Parser::TryParseQualIdent() { |
8509 if (CurrentToken() != Token::kIDENT) { | 8323 if (CurrentToken() != Token::kIDENT) { |
8510 return false; | 8324 return false; |
8511 } | 8325 } |
8512 ConsumeToken(); | 8326 ConsumeToken(); |
8513 if (CurrentToken() == Token::kPERIOD) { | 8327 if (CurrentToken() == Token::kPERIOD) { |
8514 ConsumeToken(); | 8328 ConsumeToken(); |
8515 if (CurrentToken() != Token::kIDENT) { | 8329 if (CurrentToken() != Token::kIDENT) { |
8516 return false; | 8330 return false; |
8517 } | 8331 } |
8518 ConsumeToken(); | 8332 ConsumeToken(); |
8519 } | 8333 } |
8520 return true; | 8334 return true; |
8521 } | 8335 } |
8522 | 8336 |
8523 | |
8524 // Returns true if the next tokens can be parsed as a type with optional | 8337 // Returns true if the next tokens can be parsed as a type with optional |
8525 // type parameters. Current token position is not restored. | 8338 // type parameters. Current token position is not restored. |
8526 // Allow 'void' as type if 'allow_void' is true. | 8339 // Allow 'void' as type if 'allow_void' is true. |
8527 // Note that 'void Function()' is always allowed, since it is a function type | 8340 // Note that 'void Function()' is always allowed, since it is a function type |
8528 // and not the void type. | 8341 // and not the void type. |
8529 bool Parser::TryParseType(bool allow_void) { | 8342 bool Parser::TryParseType(bool allow_void) { |
8530 bool found = false; | 8343 bool found = false; |
8531 if (CurrentToken() == Token::kVOID) { | 8344 if (CurrentToken() == Token::kVOID) { |
8532 ConsumeToken(); | 8345 ConsumeToken(); |
8533 if (allow_void) { | 8346 if (allow_void) { |
(...skipping 19 matching lines...) Expand all Loading... |
8553 if (CurrentToken() == Token::kLPAREN) { | 8366 if (CurrentToken() == Token::kLPAREN) { |
8554 SkipToMatchingParenthesis(); | 8367 SkipToMatchingParenthesis(); |
8555 } else { | 8368 } else { |
8556 return false; | 8369 return false; |
8557 } | 8370 } |
8558 found = true; | 8371 found = true; |
8559 } | 8372 } |
8560 return found; | 8373 return found; |
8561 } | 8374 } |
8562 | 8375 |
8563 | |
8564 // Look ahead to detect whether the next tokens should be parsed as | 8376 // Look ahead to detect whether the next tokens should be parsed as |
8565 // a variable declaration. Ignores optional metadata. | 8377 // a variable declaration. Ignores optional metadata. |
8566 // Returns true if we detect the token pattern: | 8378 // Returns true if we detect the token pattern: |
8567 // 'var' | 8379 // 'var' |
8568 // | 'final' | 8380 // | 'final' |
8569 // | const [type] ident (';' | '=' | ',') | 8381 // | const [type] ident (';' | '=' | ',') |
8570 // | type ident (';' | '=' | ',') | 8382 // | type ident (';' | '=' | ',') |
8571 // Token position remains unchanged. | 8383 // Token position remains unchanged. |
8572 bool Parser::IsVariableDeclaration() { | 8384 bool Parser::IsVariableDeclaration() { |
8573 if ((CurrentToken() == Token::kVAR) || (CurrentToken() == Token::kFINAL)) { | 8385 if ((CurrentToken() == Token::kVAR) || (CurrentToken() == Token::kFINAL)) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8617 if ((CurrentToken() == Token::kSEMICOLON) || | 8429 if ((CurrentToken() == Token::kSEMICOLON) || |
8618 (CurrentToken() == Token::kCOMMA) || | 8430 (CurrentToken() == Token::kCOMMA) || |
8619 (CurrentToken() == Token::kASSIGN)) { | 8431 (CurrentToken() == Token::kASSIGN)) { |
8620 is_var_decl = true; | 8432 is_var_decl = true; |
8621 } | 8433 } |
8622 } | 8434 } |
8623 SetPosition(saved_pos); | 8435 SetPosition(saved_pos); |
8624 return is_var_decl; | 8436 return is_var_decl; |
8625 } | 8437 } |
8626 | 8438 |
8627 | |
8628 // Look ahead to see if the following tokens are a return type followed | 8439 // Look ahead to see if the following tokens are a return type followed |
8629 // by an identifier. | 8440 // by an identifier. |
8630 bool Parser::IsFunctionReturnType() { | 8441 bool Parser::IsFunctionReturnType() { |
8631 TokenPosScope decl_pos(this); | 8442 TokenPosScope decl_pos(this); |
8632 if (TryParseType(true)) { | 8443 if (TryParseType(true)) { |
8633 if (IsIdentifier()) { | 8444 if (IsIdentifier()) { |
8634 // Return type followed by function name. | 8445 // Return type followed by function name. |
8635 return true; | 8446 return true; |
8636 } | 8447 } |
8637 } | 8448 } |
8638 return false; | 8449 return false; |
8639 } | 8450 } |
8640 | 8451 |
8641 | |
8642 // Look ahead to detect whether the next tokens should be parsed as | 8452 // Look ahead to detect whether the next tokens should be parsed as |
8643 // a function declaration. Token position remains unchanged. | 8453 // a function declaration. Token position remains unchanged. |
8644 bool Parser::IsFunctionDeclaration() { | 8454 bool Parser::IsFunctionDeclaration() { |
8645 bool is_external = false; | 8455 bool is_external = false; |
8646 TokenPosScope decl_pos(this); | 8456 TokenPosScope decl_pos(this); |
8647 SkipMetadata(); | 8457 SkipMetadata(); |
8648 if ((is_top_level_) && (CurrentToken() == Token::kEXTERNAL)) { | 8458 if ((is_top_level_) && (CurrentToken() == Token::kEXTERNAL)) { |
8649 // Skip over 'external' for top-level function declarations. | 8459 // Skip over 'external' for top-level function declarations. |
8650 is_external = true; | 8460 is_external = true; |
8651 ConsumeToken(); | 8461 ConsumeToken(); |
(...skipping 23 matching lines...) Expand all Loading... |
8675 // Check parameter list and the following token. | 8485 // Check parameter list and the following token. |
8676 SkipToMatchingParenthesis(); | 8486 SkipToMatchingParenthesis(); |
8677 if ((CurrentToken() == Token::kLBRACE) || (CurrentToken() == Token::kARROW) || | 8487 if ((CurrentToken() == Token::kLBRACE) || (CurrentToken() == Token::kARROW) || |
8678 (is_top_level_ && IsSymbol(Symbols::Native())) || is_external || | 8488 (is_top_level_ && IsSymbol(Symbols::Native())) || is_external || |
8679 IsSymbol(Symbols::Async()) || IsSymbol(Symbols::Sync())) { | 8489 IsSymbol(Symbols::Async()) || IsSymbol(Symbols::Sync())) { |
8680 return true; | 8490 return true; |
8681 } | 8491 } |
8682 return false; | 8492 return false; |
8683 } | 8493 } |
8684 | 8494 |
8685 | |
8686 bool Parser::IsTopLevelAccessor() { | 8495 bool Parser::IsTopLevelAccessor() { |
8687 const TokenPosScope saved_pos(this); | 8496 const TokenPosScope saved_pos(this); |
8688 if (CurrentToken() == Token::kEXTERNAL) { | 8497 if (CurrentToken() == Token::kEXTERNAL) { |
8689 ConsumeToken(); | 8498 ConsumeToken(); |
8690 } | 8499 } |
8691 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 8500 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
8692 return true; | 8501 return true; |
8693 } | 8502 } |
8694 if (TryParseType(true)) { | 8503 if (TryParseType(true)) { |
8695 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 8504 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
8696 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 8505 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
8697 return true; | 8506 return true; |
8698 } | 8507 } |
8699 } | 8508 } |
8700 } | 8509 } |
8701 return false; | 8510 return false; |
8702 } | 8511 } |
8703 | 8512 |
8704 | |
8705 bool Parser::IsFunctionLiteral() { | 8513 bool Parser::IsFunctionLiteral() { |
8706 if (!allow_function_literals_) { | 8514 if (!allow_function_literals_) { |
8707 return false; | 8515 return false; |
8708 } | 8516 } |
8709 if ((CurrentToken() == Token::kLPAREN) || (CurrentToken() == Token::kLT)) { | 8517 if ((CurrentToken() == Token::kLPAREN) || (CurrentToken() == Token::kLT)) { |
8710 TokenPosScope saved_pos(this); | 8518 TokenPosScope saved_pos(this); |
8711 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) { | 8519 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) { |
8712 return false; | 8520 return false; |
8713 } | 8521 } |
8714 if (CurrentToken() != Token::kLPAREN) { | 8522 if (CurrentToken() != Token::kLPAREN) { |
8715 return false; | 8523 return false; |
8716 } | 8524 } |
8717 SkipToMatchingParenthesis(); | 8525 SkipToMatchingParenthesis(); |
8718 ParseFunctionModifier(); | 8526 ParseFunctionModifier(); |
8719 if ((CurrentToken() == Token::kLBRACE) || | 8527 if ((CurrentToken() == Token::kLBRACE) || |
8720 (CurrentToken() == Token::kARROW)) { | 8528 (CurrentToken() == Token::kARROW)) { |
8721 return true; | 8529 return true; |
8722 } | 8530 } |
8723 } | 8531 } |
8724 return false; | 8532 return false; |
8725 } | 8533 } |
8726 | 8534 |
8727 | |
8728 // Current token position is the token after the opening ( of the for | 8535 // Current token position is the token after the opening ( of the for |
8729 // statement. Returns true if we recognize a for ( .. in expr) | 8536 // statement. Returns true if we recognize a for ( .. in expr) |
8730 // statement. | 8537 // statement. |
8731 bool Parser::IsForInStatement() { | 8538 bool Parser::IsForInStatement() { |
8732 const TokenPosScope saved_pos(this); | 8539 const TokenPosScope saved_pos(this); |
8733 // Allow const modifier as well when recognizing a for-in statement | 8540 // Allow const modifier as well when recognizing a for-in statement |
8734 // pattern. We will get an error later if the loop variable is | 8541 // pattern. We will get an error later if the loop variable is |
8735 // declared with const. | 8542 // declared with const. |
8736 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL || | 8543 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL || |
8737 CurrentToken() == Token::kCONST) { | 8544 CurrentToken() == Token::kCONST) { |
8738 ConsumeToken(); | 8545 ConsumeToken(); |
8739 } | 8546 } |
8740 if (IsIdentifier()) { | 8547 if (IsIdentifier()) { |
8741 if (LookaheadToken(1) == Token::kIN) { | 8548 if (LookaheadToken(1) == Token::kIN) { |
8742 return true; | 8549 return true; |
8743 } else if (TryParseType(false)) { | 8550 } else if (TryParseType(false)) { |
8744 if (IsIdentifier()) { | 8551 if (IsIdentifier()) { |
8745 ConsumeToken(); | 8552 ConsumeToken(); |
8746 } | 8553 } |
8747 return CurrentToken() == Token::kIN; | 8554 return CurrentToken() == Token::kIN; |
8748 } | 8555 } |
8749 } | 8556 } |
8750 return false; | 8557 return false; |
8751 } | 8558 } |
8752 | 8559 |
8753 | |
8754 static bool ContainsAbruptCompletingStatement(SequenceNode* seq); | 8560 static bool ContainsAbruptCompletingStatement(SequenceNode* seq); |
8755 | 8561 |
8756 static bool IsAbruptCompleting(AstNode* statement) { | 8562 static bool IsAbruptCompleting(AstNode* statement) { |
8757 return statement->IsReturnNode() || statement->IsJumpNode() || | 8563 return statement->IsReturnNode() || statement->IsJumpNode() || |
8758 statement->IsThrowNode() || | 8564 statement->IsThrowNode() || |
8759 (statement->IsSequenceNode() && | 8565 (statement->IsSequenceNode() && |
8760 ContainsAbruptCompletingStatement(statement->AsSequenceNode())); | 8566 ContainsAbruptCompletingStatement(statement->AsSequenceNode())); |
8761 } | 8567 } |
8762 | 8568 |
8763 | |
8764 static bool ContainsAbruptCompletingStatement(SequenceNode* seq) { | 8569 static bool ContainsAbruptCompletingStatement(SequenceNode* seq) { |
8765 for (int i = 0; i < seq->length(); i++) { | 8570 for (int i = 0; i < seq->length(); i++) { |
8766 if (IsAbruptCompleting(seq->NodeAt(i))) { | 8571 if (IsAbruptCompleting(seq->NodeAt(i))) { |
8767 return true; | 8572 return true; |
8768 } | 8573 } |
8769 } | 8574 } |
8770 return false; | 8575 return false; |
8771 } | 8576 } |
8772 | 8577 |
8773 | |
8774 void Parser::ParseStatementSequence() { | 8578 void Parser::ParseStatementSequence() { |
8775 TRACE_PARSER("ParseStatementSequence"); | 8579 TRACE_PARSER("ParseStatementSequence"); |
8776 const bool dead_code_allowed = true; | 8580 const bool dead_code_allowed = true; |
8777 bool abrupt_completing_seen = false; | 8581 bool abrupt_completing_seen = false; |
8778 RecursionChecker rc(this); | 8582 RecursionChecker rc(this); |
8779 while (CurrentToken() != Token::kRBRACE) { | 8583 while (CurrentToken() != Token::kRBRACE) { |
8780 const TokenPosition statement_pos = TokenPos(); | 8584 const TokenPosition statement_pos = TokenPos(); |
8781 AstNode* statement = ParseStatement(); | 8585 AstNode* statement = ParseStatement(); |
8782 // Do not add statements with no effect (e.g., LoadLocalNode). | 8586 // Do not add statements with no effect (e.g., LoadLocalNode). |
8783 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 8587 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
8784 // Skip load local. | 8588 // Skip load local. |
8785 continue; | 8589 continue; |
8786 } | 8590 } |
8787 if (statement != NULL) { | 8591 if (statement != NULL) { |
8788 if (!dead_code_allowed && abrupt_completing_seen) { | 8592 if (!dead_code_allowed && abrupt_completing_seen) { |
8789 ReportError(statement_pos, | 8593 ReportError(statement_pos, |
8790 "dead code after abrupt completing statement"); | 8594 "dead code after abrupt completing statement"); |
8791 } | 8595 } |
8792 current_block_->statements->Add(statement); | 8596 current_block_->statements->Add(statement); |
8793 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8597 abrupt_completing_seen |= IsAbruptCompleting(statement); |
8794 } | 8598 } |
8795 } | 8599 } |
8796 } | 8600 } |
8797 | 8601 |
8798 | |
8799 // Parse nested statement of if, while, for, etc. We automatically generate | 8602 // Parse nested statement of if, while, for, etc. We automatically generate |
8800 // a sequence of one statement if there are no curly braces. | 8603 // a sequence of one statement if there are no curly braces. |
8801 // The argument 'parsing_loop_body' indicates the parsing of a loop statement. | 8604 // The argument 'parsing_loop_body' indicates the parsing of a loop statement. |
8802 SequenceNode* Parser::ParseNestedStatement(bool parsing_loop_body, | 8605 SequenceNode* Parser::ParseNestedStatement(bool parsing_loop_body, |
8803 SourceLabel* label) { | 8606 SourceLabel* label) { |
8804 TRACE_PARSER("ParseNestedStatement"); | 8607 TRACE_PARSER("ParseNestedStatement"); |
8805 if (parsing_loop_body) { | 8608 if (parsing_loop_body) { |
8806 OpenLoopBlock(); | 8609 OpenLoopBlock(); |
8807 } else { | 8610 } else { |
8808 OpenBlock(); | 8611 OpenBlock(); |
8809 } | 8612 } |
8810 if (label != NULL) { | 8613 if (label != NULL) { |
8811 current_block_->scope->AddLabel(label); | 8614 current_block_->scope->AddLabel(label); |
8812 } | 8615 } |
8813 if (CurrentToken() == Token::kLBRACE) { | 8616 if (CurrentToken() == Token::kLBRACE) { |
8814 ConsumeToken(); | 8617 ConsumeToken(); |
8815 ParseStatementSequence(); | 8618 ParseStatementSequence(); |
8816 ExpectToken(Token::kRBRACE); | 8619 ExpectToken(Token::kRBRACE); |
8817 } else { | 8620 } else { |
8818 RecursionChecker rc(this); | 8621 RecursionChecker rc(this); |
8819 AstNode* statement = ParseStatement(); | 8622 AstNode* statement = ParseStatement(); |
8820 if (statement != NULL) { | 8623 if (statement != NULL) { |
8821 current_block_->statements->Add(statement); | 8624 current_block_->statements->Add(statement); |
8822 } | 8625 } |
8823 } | 8626 } |
8824 SequenceNode* sequence = CloseBlock(); | 8627 SequenceNode* sequence = CloseBlock(); |
8825 return sequence; | 8628 return sequence; |
8826 } | 8629 } |
8827 | 8630 |
8828 | |
8829 AstNode* Parser::ParseIfStatement(String* label_name) { | 8631 AstNode* Parser::ParseIfStatement(String* label_name) { |
8830 TRACE_PARSER("ParseIfStatement"); | 8632 TRACE_PARSER("ParseIfStatement"); |
8831 ASSERT(CurrentToken() == Token::kIF); | 8633 ASSERT(CurrentToken() == Token::kIF); |
8832 const TokenPosition if_pos = TokenPos(); | 8634 const TokenPosition if_pos = TokenPos(); |
8833 SourceLabel* label = NULL; | 8635 SourceLabel* label = NULL; |
8834 if (label_name != NULL) { | 8636 if (label_name != NULL) { |
8835 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 8637 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
8836 OpenBlock(); | 8638 OpenBlock(); |
8837 current_block_->scope->AddLabel(label); | 8639 current_block_->scope->AddLabel(label); |
8838 } | 8640 } |
(...skipping 12 matching lines...) Expand all Loading... |
8851 new (Z) IfNode(if_pos, cond_expr, true_branch, false_branch); | 8653 new (Z) IfNode(if_pos, cond_expr, true_branch, false_branch); |
8852 if (label != NULL) { | 8654 if (label != NULL) { |
8853 current_block_->statements->Add(if_node); | 8655 current_block_->statements->Add(if_node); |
8854 SequenceNode* sequence = CloseBlock(); | 8656 SequenceNode* sequence = CloseBlock(); |
8855 sequence->set_label(label); | 8657 sequence->set_label(label); |
8856 if_node = sequence; | 8658 if_node = sequence; |
8857 } | 8659 } |
8858 return if_node; | 8660 return if_node; |
8859 } | 8661 } |
8860 | 8662 |
8861 | |
8862 // Return true if the type class of the given value implements the | 8663 // Return true if the type class of the given value implements the |
8863 // == operator. | 8664 // == operator. |
8864 static bool ImplementsEqualOperator(Zone* zone, const Instance& value) { | 8665 static bool ImplementsEqualOperator(Zone* zone, const Instance& value) { |
8865 Class& cls = Class::Handle(value.clazz()); | 8666 Class& cls = Class::Handle(value.clazz()); |
8866 const Function& equal_op = Function::Handle( | 8667 const Function& equal_op = Function::Handle( |
8867 zone, | 8668 zone, |
8868 Resolver::ResolveDynamicAnyArgs(zone, cls, Symbols::EqualOperator())); | 8669 Resolver::ResolveDynamicAnyArgs(zone, cls, Symbols::EqualOperator())); |
8869 ASSERT(!equal_op.IsNull()); | 8670 ASSERT(!equal_op.IsNull()); |
8870 cls = equal_op.Owner(); | 8671 cls = equal_op.Owner(); |
8871 return !cls.IsObjectClass(); | 8672 return !cls.IsObjectClass(); |
8872 } | 8673 } |
8873 | 8674 |
8874 | |
8875 // Check that all case expressions are of the same type, either int, String, | 8675 // Check that all case expressions are of the same type, either int, String, |
8876 // or any other class that does not override the == operator. | 8676 // or any other class that does not override the == operator. |
8877 // The expressions are compile-time constants and are thus in the form | 8677 // The expressions are compile-time constants and are thus in the form |
8878 // of a LiteralNode. | 8678 // of a LiteralNode. |
8879 RawClass* Parser::CheckCaseExpressions( | 8679 RawClass* Parser::CheckCaseExpressions( |
8880 const GrowableArray<LiteralNode*>& values) { | 8680 const GrowableArray<LiteralNode*>& values) { |
8881 const intptr_t num_expressions = values.length(); | 8681 const intptr_t num_expressions = values.length(); |
8882 if (num_expressions == 0) { | 8682 if (num_expressions == 0) { |
8883 return Object::dynamic_class(); | 8683 return Object::dynamic_class(); |
8884 } | 8684 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8920 } | 8720 } |
8921 } | 8721 } |
8922 if (first_value.IsInteger()) { | 8722 if (first_value.IsInteger()) { |
8923 return Type::Handle(Z, Type::IntType()).type_class(); | 8723 return Type::Handle(Z, Type::IntType()).type_class(); |
8924 } else if (first_value.IsString()) { | 8724 } else if (first_value.IsString()) { |
8925 return Type::Handle(Z, Type::StringType()).type_class(); | 8725 return Type::Handle(Z, Type::StringType()).type_class(); |
8926 } | 8726 } |
8927 return first_value.clazz(); | 8727 return first_value.clazz(); |
8928 } | 8728 } |
8929 | 8729 |
8930 | |
8931 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 8730 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
8932 GrowableArray<LiteralNode*>* case_expr_values, | 8731 GrowableArray<LiteralNode*>* case_expr_values, |
8933 SourceLabel* case_label) { | 8732 SourceLabel* case_label) { |
8934 TRACE_PARSER("ParseCaseClause"); | 8733 TRACE_PARSER("ParseCaseClause"); |
8935 bool default_seen = false; | 8734 bool default_seen = false; |
8936 const TokenPosition case_pos = TokenPos(); | 8735 const TokenPosition case_pos = TokenPos(); |
8937 // The case expressions node sequence does not own the enclosing scope. | 8736 // The case expressions node sequence does not own the enclosing scope. |
8938 SequenceNode* case_expressions = new (Z) SequenceNode(case_pos, NULL); | 8737 SequenceNode* case_expressions = new (Z) SequenceNode(case_pos, NULL); |
8939 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 8738 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
8940 if (CurrentToken() == Token::kCASE) { | 8739 if (CurrentToken() == Token::kCASE) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8998 if (statement != NULL) { | 8797 if (statement != NULL) { |
8999 current_block_->statements->Add(statement); | 8798 current_block_->statements->Add(statement); |
9000 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8799 abrupt_completing_seen |= IsAbruptCompleting(statement); |
9001 } | 8800 } |
9002 } | 8801 } |
9003 SequenceNode* statements = CloseBlock(); | 8802 SequenceNode* statements = CloseBlock(); |
9004 return new (Z) CaseNode(case_pos, case_label, case_expressions, default_seen, | 8803 return new (Z) CaseNode(case_pos, case_label, case_expressions, default_seen, |
9005 switch_expr_value, statements); | 8804 switch_expr_value, statements); |
9006 } | 8805 } |
9007 | 8806 |
9008 | |
9009 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 8807 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
9010 TRACE_PARSER("ParseSwitchStatement"); | 8808 TRACE_PARSER("ParseSwitchStatement"); |
9011 ASSERT(CurrentToken() == Token::kSWITCH); | 8809 ASSERT(CurrentToken() == Token::kSWITCH); |
9012 const TokenPosition switch_pos = TokenPos(); | 8810 const TokenPosition switch_pos = TokenPos(); |
9013 SourceLabel* label = | 8811 SourceLabel* label = |
9014 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 8812 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
9015 ConsumeToken(); | 8813 ConsumeToken(); |
9016 ExpectToken(Token::kLPAREN); | 8814 ExpectToken(Token::kLPAREN); |
9017 const TokenPosition expr_pos = TokenPos(); | 8815 const TokenPosition expr_pos = TokenPos(); |
9018 AstNode* switch_expr = | 8816 AstNode* switch_expr = |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9097 if (unresolved_label != NULL) { | 8895 if (unresolved_label != NULL) { |
9098 ReportError("unresolved reference to label '%s'", | 8896 ReportError("unresolved reference to label '%s'", |
9099 unresolved_label->name().ToCString()); | 8897 unresolved_label->name().ToCString()); |
9100 } | 8898 } |
9101 | 8899 |
9102 SequenceNode* switch_body = CloseBlock(); | 8900 SequenceNode* switch_body = CloseBlock(); |
9103 ExpectToken(Token::kRBRACE); | 8901 ExpectToken(Token::kRBRACE); |
9104 return new (Z) SwitchNode(switch_pos, label, switch_body); | 8902 return new (Z) SwitchNode(switch_pos, label, switch_body); |
9105 } | 8903 } |
9106 | 8904 |
9107 | |
9108 AstNode* Parser::ParseWhileStatement(String* label_name) { | 8905 AstNode* Parser::ParseWhileStatement(String* label_name) { |
9109 TRACE_PARSER("ParseWhileStatement"); | 8906 TRACE_PARSER("ParseWhileStatement"); |
9110 const TokenPosition while_pos = TokenPos(); | 8907 const TokenPosition while_pos = TokenPos(); |
9111 SourceLabel* label = | 8908 SourceLabel* label = |
9112 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 8909 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
9113 ConsumeToken(); | 8910 ConsumeToken(); |
9114 ExpectToken(Token::kLPAREN); | 8911 ExpectToken(Token::kLPAREN); |
9115 SequenceNode* await_preamble = NULL; | 8912 SequenceNode* await_preamble = NULL; |
9116 AstNode* cond_expr = | 8913 AstNode* cond_expr = |
9117 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8914 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
9118 ExpectToken(Token::kRPAREN); | 8915 ExpectToken(Token::kRPAREN); |
9119 const bool parsing_loop_body = true; | 8916 const bool parsing_loop_body = true; |
9120 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 8917 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
9121 WhileNode* while_node = new (Z) | 8918 WhileNode* while_node = new (Z) |
9122 WhileNode(while_pos, label, cond_expr, await_preamble, while_body); | 8919 WhileNode(while_pos, label, cond_expr, await_preamble, while_body); |
9123 return while_node; | 8920 return while_node; |
9124 } | 8921 } |
9125 | 8922 |
9126 | |
9127 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 8923 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
9128 TRACE_PARSER("ParseDoWhileStatement"); | 8924 TRACE_PARSER("ParseDoWhileStatement"); |
9129 const TokenPosition do_pos = TokenPos(); | 8925 const TokenPosition do_pos = TokenPos(); |
9130 SourceLabel* label = | 8926 SourceLabel* label = |
9131 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 8927 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
9132 ConsumeToken(); | 8928 ConsumeToken(); |
9133 const bool parsing_loop_body = true; | 8929 const bool parsing_loop_body = true; |
9134 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 8930 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
9135 ExpectToken(Token::kWHILE); | 8931 ExpectToken(Token::kWHILE); |
9136 ExpectToken(Token::kLPAREN); | 8932 ExpectToken(Token::kLPAREN); |
9137 SequenceNode* await_preamble = NULL; | 8933 SequenceNode* await_preamble = NULL; |
9138 TokenPosition expr_pos = TokenPos(); | 8934 TokenPosition expr_pos = TokenPos(); |
9139 AstNode* cond_expr = | 8935 AstNode* cond_expr = |
9140 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8936 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
9141 if (await_preamble != NULL) { | 8937 if (await_preamble != NULL) { |
9142 // Prepend the preamble to the condition. | 8938 // Prepend the preamble to the condition. |
9143 LetNode* await_cond = new (Z) LetNode(expr_pos); | 8939 LetNode* await_cond = new (Z) LetNode(expr_pos); |
9144 await_cond->AddNode(await_preamble); | 8940 await_cond->AddNode(await_preamble); |
9145 await_cond->AddNode(cond_expr); | 8941 await_cond->AddNode(cond_expr); |
9146 cond_expr = await_cond; | 8942 cond_expr = await_cond; |
9147 } | 8943 } |
9148 ExpectToken(Token::kRPAREN); | 8944 ExpectToken(Token::kRPAREN); |
9149 ExpectSemicolon(); | 8945 ExpectSemicolon(); |
9150 return new (Z) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 8946 return new (Z) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
9151 } | 8947 } |
9152 | 8948 |
9153 | |
9154 static LocalVariable* LookupSavedTryContextVar(LocalScope* scope) { | 8949 static LocalVariable* LookupSavedTryContextVar(LocalScope* scope) { |
9155 LocalVariable* var = | 8950 LocalVariable* var = |
9156 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 8951 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
9157 ASSERT((var != NULL) && !var->is_captured()); | 8952 ASSERT((var != NULL) && !var->is_captured()); |
9158 return var; | 8953 return var; |
9159 } | 8954 } |
9160 | 8955 |
9161 | |
9162 static LocalVariable* LookupAsyncSavedTryContextVar(Thread* thread, | 8956 static LocalVariable* LookupAsyncSavedTryContextVar(Thread* thread, |
9163 LocalScope* scope, | 8957 LocalScope* scope, |
9164 uint16_t try_index) { | 8958 uint16_t try_index) { |
9165 Zone* zone = thread->zone(); | 8959 Zone* zone = thread->zone(); |
9166 const String& async_saved_try_ctx_name = String::ZoneHandle( | 8960 const String& async_saved_try_ctx_name = String::ZoneHandle( |
9167 zone, Symbols::NewFormatted( | 8961 zone, Symbols::NewFormatted( |
9168 thread, "%s%d", | 8962 thread, "%s%d", |
9169 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), try_index)); | 8963 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), try_index)); |
9170 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); | 8964 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); |
9171 ASSERT(var != NULL); | 8965 ASSERT(var != NULL); |
9172 return var; | 8966 return var; |
9173 } | 8967 } |
9174 | 8968 |
9175 | |
9176 // If the await or yield being parsed is in a try block, the continuation code | 8969 // If the await or yield being parsed is in a try block, the continuation code |
9177 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, | 8970 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, |
9178 // and the stack-based variable :saved_try_ctx_var of the outer try block. | 8971 // and the stack-based variable :saved_try_ctx_var of the outer try block. |
9179 // The inner :saved_try_ctx_var is used by a finally clause handling an | 8972 // The inner :saved_try_ctx_var is used by a finally clause handling an |
9180 // exception thrown by the continuation code in a try block or catch block. | 8973 // exception thrown by the continuation code in a try block or catch block. |
9181 // If no finally clause exists, the catch or finally clause of the outer try | 8974 // If no finally clause exists, the catch or finally clause of the outer try |
9182 // block, if any, uses the outer :saved_try_ctx_var to handle the exception. | 8975 // block, if any, uses the outer :saved_try_ctx_var to handle the exception. |
9183 // | 8976 // |
9184 // * Try blocks and catch blocks: | 8977 // * Try blocks and catch blocks: |
9185 // Set the context variable for this try block and for the outer try block. | 8978 // Set the context variable for this try block and for the outer try block. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9221 } | 9014 } |
9222 // An async or async* has an implicitly created try-catch around the | 9015 // An async or async* has an implicitly created try-catch around the |
9223 // function body, so the await or yield inside the async closure should always | 9016 // function body, so the await or yield inside the async closure should always |
9224 // be created with a try scope. | 9017 // be created with a try scope. |
9225 ASSERT((*saved_try_ctx != NULL) || innermost_function().IsAsyncFunction() || | 9018 ASSERT((*saved_try_ctx != NULL) || innermost_function().IsAsyncFunction() || |
9226 innermost_function().IsAsyncGenerator() || | 9019 innermost_function().IsAsyncGenerator() || |
9227 innermost_function().IsSyncGenClosure() || | 9020 innermost_function().IsSyncGenClosure() || |
9228 innermost_function().IsSyncGenerator()); | 9021 innermost_function().IsSyncGenerator()); |
9229 } | 9022 } |
9230 | 9023 |
9231 | |
9232 // Build an AST node for static call to Dart function print(str). | 9024 // Build an AST node for static call to Dart function print(str). |
9233 // Used during debugging to insert print in generated dart code. | 9025 // Used during debugging to insert print in generated dart code. |
9234 AstNode* Parser::DartPrint(const char* str) { | 9026 AstNode* Parser::DartPrint(const char* str) { |
9235 const Library& lib = Library::Handle(Library::CoreLibrary()); | 9027 const Library& lib = Library::Handle(Library::CoreLibrary()); |
9236 const Function& print_fn = | 9028 const Function& print_fn = |
9237 Function::ZoneHandle(Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 9029 Function::ZoneHandle(Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
9238 ASSERT(!print_fn.IsNull()); | 9030 ASSERT(!print_fn.IsNull()); |
9239 ArgumentListNode* one_arg = | 9031 ArgumentListNode* one_arg = |
9240 new (Z) ArgumentListNode(TokenPosition::kNoSource); | 9032 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
9241 String& msg = String::ZoneHandle(Symbols::NewFormatted(T, "%s", str)); | 9033 String& msg = String::ZoneHandle(Symbols::NewFormatted(T, "%s", str)); |
9242 one_arg->Add(new (Z) LiteralNode(TokenPosition::kNoSource, msg)); | 9034 one_arg->Add(new (Z) LiteralNode(TokenPosition::kNoSource, msg)); |
9243 AstNode* print_call = | 9035 AstNode* print_call = |
9244 new (Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg); | 9036 new (Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg); |
9245 return print_call; | 9037 return print_call; |
9246 } | 9038 } |
9247 | 9039 |
9248 | |
9249 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 9040 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
9250 TRACE_PARSER("ParseAwaitForStatement"); | 9041 TRACE_PARSER("ParseAwaitForStatement"); |
9251 ASSERT(IsAwaitKeyword()); | 9042 ASSERT(IsAwaitKeyword()); |
9252 const TokenPosition await_for_pos = TokenPos(); | 9043 const TokenPosition await_for_pos = TokenPos(); |
9253 ConsumeToken(); // await. | 9044 ConsumeToken(); // await. |
9254 ASSERT(CurrentToken() == Token::kFOR); | 9045 ASSERT(CurrentToken() == Token::kFOR); |
9255 ConsumeToken(); // for. | 9046 ConsumeToken(); // for. |
9256 ExpectToken(Token::kLPAREN); | 9047 ExpectToken(Token::kLPAREN); |
9257 | 9048 |
9258 if (!innermost_function().IsAsyncFunction() && | 9049 if (!innermost_function().IsAsyncFunction() && |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9556 AstNode* try_catch_node = | 9347 AstNode* try_catch_node = |
9557 new (Z) TryCatchNode(await_for_pos, try_block, context_var, catch_clause, | 9348 new (Z) TryCatchNode(await_for_pos, try_block, context_var, catch_clause, |
9558 finally_clause, try_index, finally_clause); | 9349 finally_clause, try_index, finally_clause); |
9559 | 9350 |
9560 ASSERT(current_block_ == await_for_block); | 9351 ASSERT(current_block_ == await_for_block); |
9561 await_for_block->statements->Add(try_catch_node); | 9352 await_for_block->statements->Add(try_catch_node); |
9562 | 9353 |
9563 return CloseBlock(); // Implicit block around while loop. | 9354 return CloseBlock(); // Implicit block around while loop. |
9564 } | 9355 } |
9565 | 9356 |
9566 | |
9567 AstNode* Parser::ParseForInStatement(TokenPosition forin_pos, | 9357 AstNode* Parser::ParseForInStatement(TokenPosition forin_pos, |
9568 SourceLabel* label) { | 9358 SourceLabel* label) { |
9569 TRACE_PARSER("ParseForInStatement"); | 9359 TRACE_PARSER("ParseForInStatement"); |
9570 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 9360 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
9571 if (CurrentToken() == Token::kCONST) { | 9361 if (CurrentToken() == Token::kCONST) { |
9572 ReportError("Loop variable cannot be 'const'"); | 9362 ReportError("Loop variable cannot be 'const'"); |
9573 } | 9363 } |
9574 const String* loop_var_name = NULL; | 9364 const String* loop_var_name = NULL; |
9575 TokenPosition loop_var_pos = TokenPosition::kNoSource; | 9365 TokenPosition loop_var_pos = TokenPosition::kNoSource; |
9576 bool new_loop_var = false; | 9366 bool new_loop_var = false; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9677 | 9467 |
9678 SequenceNode* for_loop_statement = CloseBlock(); | 9468 SequenceNode* for_loop_statement = CloseBlock(); |
9679 | 9469 |
9680 AstNode* while_statement = new (Z) | 9470 AstNode* while_statement = new (Z) |
9681 WhileNode(forin_pos, label, iterator_moveNext, NULL, for_loop_statement); | 9471 WhileNode(forin_pos, label, iterator_moveNext, NULL, for_loop_statement); |
9682 current_block_->statements->Add(while_statement); | 9472 current_block_->statements->Add(while_statement); |
9683 | 9473 |
9684 return CloseBlock(); // Implicit block around while loop. | 9474 return CloseBlock(); // Implicit block around while loop. |
9685 } | 9475 } |
9686 | 9476 |
9687 | |
9688 AstNode* Parser::ParseForStatement(String* label_name) { | 9477 AstNode* Parser::ParseForStatement(String* label_name) { |
9689 TRACE_PARSER("ParseForStatement"); | 9478 TRACE_PARSER("ParseForStatement"); |
9690 const TokenPosition for_pos = TokenPos(); | 9479 const TokenPosition for_pos = TokenPos(); |
9691 ConsumeToken(); | 9480 ConsumeToken(); |
9692 ExpectToken(Token::kLPAREN); | 9481 ExpectToken(Token::kLPAREN); |
9693 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 9482 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
9694 if (IsForInStatement()) { | 9483 if (IsForInStatement()) { |
9695 return ParseForInStatement(for_pos, label); | 9484 return ParseForInStatement(for_pos, label); |
9696 } | 9485 } |
9697 // Open a block that contains the loop variable. Make it a loop block so | 9486 // Open a block that contains the loop variable. Make it a loop block so |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9741 } | 9530 } |
9742 } | 9531 } |
9743 AstNode* for_node = new (Z) | 9532 AstNode* for_node = new (Z) |
9744 ForNode(for_pos, label, NodeAsSequenceNode(init_pos, initializer, NULL), | 9533 ForNode(for_pos, label, NodeAsSequenceNode(init_pos, initializer, NULL), |
9745 condition, condition_preamble, | 9534 condition, condition_preamble, |
9746 NodeAsSequenceNode(incr_pos, increment, NULL), body); | 9535 NodeAsSequenceNode(incr_pos, increment, NULL), body); |
9747 current_block_->statements->Add(for_node); | 9536 current_block_->statements->Add(for_node); |
9748 return CloseBlock(); | 9537 return CloseBlock(); |
9749 } | 9538 } |
9750 | 9539 |
9751 | |
9752 // Calling VM-internal helpers, uses implementation core library. | 9540 // Calling VM-internal helpers, uses implementation core library. |
9753 AstNode* Parser::MakeStaticCall(const String& cls_name, | 9541 AstNode* Parser::MakeStaticCall(const String& cls_name, |
9754 const String& func_name, | 9542 const String& func_name, |
9755 ArgumentListNode* arguments) { | 9543 ArgumentListNode* arguments) { |
9756 const Class& cls = Class::Handle(Z, Library::LookupCoreClass(cls_name)); | 9544 const Class& cls = Class::Handle(Z, Library::LookupCoreClass(cls_name)); |
9757 ASSERT(!cls.IsNull()); | 9545 ASSERT(!cls.IsNull()); |
9758 const intptr_t kTypeArgsLen = 0; // Not passing type args to generic func. | 9546 const intptr_t kTypeArgsLen = 0; // Not passing type args to generic func. |
9759 const Function& func = Function::ZoneHandle( | 9547 const Function& func = Function::ZoneHandle( |
9760 Z, Resolver::ResolveStatic(cls, func_name, kTypeArgsLen, | 9548 Z, Resolver::ResolveStatic(cls, func_name, kTypeArgsLen, |
9761 arguments->length(), arguments->names())); | 9549 arguments->length(), arguments->names())); |
9762 ASSERT(!func.IsNull()); | 9550 ASSERT(!func.IsNull()); |
9763 return new (Z) StaticCallNode(arguments->token_pos(), func, arguments); | 9551 return new (Z) StaticCallNode(arguments->token_pos(), func, arguments); |
9764 } | 9552 } |
9765 | 9553 |
9766 | |
9767 AstNode* Parser::ParseAssertStatement(bool is_const) { | 9554 AstNode* Parser::ParseAssertStatement(bool is_const) { |
9768 TRACE_PARSER("ParseAssertStatement"); | 9555 TRACE_PARSER("ParseAssertStatement"); |
9769 ConsumeToken(); // Consume assert keyword. | 9556 ConsumeToken(); // Consume assert keyword. |
9770 ExpectToken(Token::kLPAREN); | 9557 ExpectToken(Token::kLPAREN); |
9771 const TokenPosition condition_pos = TokenPos(); | 9558 const TokenPosition condition_pos = TokenPos(); |
9772 if (!I->asserts()) { | 9559 if (!I->asserts()) { |
9773 SkipExpr(); | 9560 SkipExpr(); |
9774 if (CurrentToken() == Token::kCOMMA) { | 9561 if (CurrentToken() == Token::kCOMMA) { |
9775 ConsumeToken(); | 9562 ConsumeToken(); |
9776 if (CurrentToken() != Token::kRPAREN) { | 9563 if (CurrentToken() != Token::kRPAREN) { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9863 assertion_check = preamble; | 9650 assertion_check = preamble; |
9864 } else { | 9651 } else { |
9865 // Build if (!condition) _AsertionError._throwNew(...) | 9652 // Build if (!condition) _AsertionError._throwNew(...) |
9866 assertion_check = new (Z) | 9653 assertion_check = new (Z) |
9867 IfNode(condition_pos, not_condition, | 9654 IfNode(condition_pos, not_condition, |
9868 NodeAsSequenceNode(condition_pos, assert_throw, NULL), NULL); | 9655 NodeAsSequenceNode(condition_pos, assert_throw, NULL), NULL); |
9869 } | 9656 } |
9870 return assertion_check; | 9657 return assertion_check; |
9871 } | 9658 } |
9872 | 9659 |
9873 | |
9874 // Populate local scope of the catch block with the catch parameters. | 9660 // Populate local scope of the catch block with the catch parameters. |
9875 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 9661 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
9876 CatchParamDesc* stack_trace_param, | 9662 CatchParamDesc* stack_trace_param, |
9877 LocalScope* scope) { | 9663 LocalScope* scope) { |
9878 if (exception_param->name != NULL) { | 9664 if (exception_param->name != NULL) { |
9879 LocalVariable* var = new (Z) | 9665 LocalVariable* var = new (Z) |
9880 LocalVariable(exception_param->token_pos, exception_param->token_pos, | 9666 LocalVariable(exception_param->token_pos, exception_param->token_pos, |
9881 *exception_param->name, *exception_param->type); | 9667 *exception_param->name, *exception_param->type); |
9882 var->set_is_final(); | 9668 var->set_is_final(); |
9883 bool added_to_scope = scope->AddVariable(var); | 9669 bool added_to_scope = scope->AddVariable(var); |
9884 ASSERT(added_to_scope); | 9670 ASSERT(added_to_scope); |
9885 exception_param->var = var; | 9671 exception_param->var = var; |
9886 } | 9672 } |
9887 if (stack_trace_param->name != NULL) { | 9673 if (stack_trace_param->name != NULL) { |
9888 LocalVariable* var = new (Z) LocalVariable( | 9674 LocalVariable* var = new (Z) LocalVariable( |
9889 stack_trace_param->token_pos, stack_trace_param->token_pos, | 9675 stack_trace_param->token_pos, stack_trace_param->token_pos, |
9890 *stack_trace_param->name, *stack_trace_param->type); | 9676 *stack_trace_param->name, *stack_trace_param->type); |
9891 var->set_is_final(); | 9677 var->set_is_final(); |
9892 bool added_to_scope = scope->AddVariable(var); | 9678 bool added_to_scope = scope->AddVariable(var); |
9893 if (!added_to_scope) { | 9679 if (!added_to_scope) { |
9894 // The name of the exception param is reused for the stack trace param. | 9680 // The name of the exception param is reused for the stack trace param. |
9895 ReportError(stack_trace_param->token_pos, | 9681 ReportError(stack_trace_param->token_pos, |
9896 "name '%s' already exists in scope", | 9682 "name '%s' already exists in scope", |
9897 stack_trace_param->name->ToCString()); | 9683 stack_trace_param->name->ToCString()); |
9898 } | 9684 } |
9899 stack_trace_param->var = var; | 9685 stack_trace_param->var = var; |
9900 } | 9686 } |
9901 } | 9687 } |
9902 | 9688 |
9903 | |
9904 // Generate code to load the exception object (:exception_var) into | 9689 // Generate code to load the exception object (:exception_var) into |
9905 // the saved exception variable (:saved_exception_var) used to rethrow. | 9690 // the saved exception variable (:saved_exception_var) used to rethrow. |
9906 // Generate code to load the stack trace object (:stack_trace_var) into | 9691 // Generate code to load the stack trace object (:stack_trace_var) into |
9907 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. | 9692 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. |
9908 void Parser::SaveExceptionAndStackTrace(SequenceNode* statements, | 9693 void Parser::SaveExceptionAndStackTrace(SequenceNode* statements, |
9909 LocalVariable* exception_var, | 9694 LocalVariable* exception_var, |
9910 LocalVariable* stack_trace_var, | 9695 LocalVariable* stack_trace_var, |
9911 LocalVariable* saved_exception_var, | 9696 LocalVariable* saved_exception_var, |
9912 LocalVariable* saved_stack_trace_var) { | 9697 LocalVariable* saved_stack_trace_var) { |
9913 ASSERT(innermost_function().IsAsyncClosure() || | 9698 ASSERT(innermost_function().IsAsyncClosure() || |
9914 innermost_function().IsAsyncFunction() || | 9699 innermost_function().IsAsyncFunction() || |
9915 innermost_function().IsSyncGenClosure() || | 9700 innermost_function().IsSyncGenClosure() || |
9916 innermost_function().IsSyncGenerator() || | 9701 innermost_function().IsSyncGenerator() || |
9917 innermost_function().IsAsyncGenClosure() || | 9702 innermost_function().IsAsyncGenClosure() || |
9918 innermost_function().IsAsyncGenerator()); | 9703 innermost_function().IsAsyncGenerator()); |
9919 | 9704 |
9920 ASSERT(saved_exception_var != NULL); | 9705 ASSERT(saved_exception_var != NULL); |
9921 ASSERT(exception_var != NULL); | 9706 ASSERT(exception_var != NULL); |
9922 statements->Add(new (Z) StoreLocalNode( | 9707 statements->Add(new (Z) StoreLocalNode( |
9923 TokenPosition::kNoSource, saved_exception_var, | 9708 TokenPosition::kNoSource, saved_exception_var, |
9924 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); | 9709 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
9925 | 9710 |
9926 ASSERT(saved_stack_trace_var != NULL); | 9711 ASSERT(saved_stack_trace_var != NULL); |
9927 ASSERT(stack_trace_var != NULL); | 9712 ASSERT(stack_trace_var != NULL); |
9928 statements->Add(new (Z) StoreLocalNode( | 9713 statements->Add(new (Z) StoreLocalNode( |
9929 TokenPosition::kNoSource, saved_stack_trace_var, | 9714 TokenPosition::kNoSource, saved_stack_trace_var, |
9930 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); | 9715 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
9931 } | 9716 } |
9932 | 9717 |
9933 | |
9934 SequenceNode* Parser::EnsureFinallyClause( | 9718 SequenceNode* Parser::EnsureFinallyClause( |
9935 bool parse, | 9719 bool parse, |
9936 bool is_async, | 9720 bool is_async, |
9937 LocalVariable* exception_var, | 9721 LocalVariable* exception_var, |
9938 LocalVariable* stack_trace_var, | 9722 LocalVariable* stack_trace_var, |
9939 LocalVariable* rethrow_exception_var, | 9723 LocalVariable* rethrow_exception_var, |
9940 LocalVariable* rethrow_stack_trace_var) { | 9724 LocalVariable* rethrow_stack_trace_var) { |
9941 TRACE_PARSER("EnsureFinallyClause"); | 9725 TRACE_PARSER("EnsureFinallyClause"); |
9942 ASSERT(parse || (is_async && (try_stack_ != NULL))); | 9726 ASSERT(parse || (is_async && (try_stack_ != NULL))); |
9943 // Increasing the loop level prevents the reuse of a parent context and forces | 9727 // Increasing the loop level prevents the reuse of a parent context and forces |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9987 ParseStatementSequence(); | 9771 ParseStatementSequence(); |
9988 ExpectToken(Token::kRBRACE); | 9772 ExpectToken(Token::kRBRACE); |
9989 } | 9773 } |
9990 SequenceNode* finally_clause = CloseBlock(); | 9774 SequenceNode* finally_clause = CloseBlock(); |
9991 if (try_stack_ != NULL) { | 9775 if (try_stack_ != NULL) { |
9992 try_stack_->exit_finally(); | 9776 try_stack_->exit_finally(); |
9993 } | 9777 } |
9994 return finally_clause; | 9778 return finally_clause; |
9995 } | 9779 } |
9996 | 9780 |
9997 | |
9998 void Parser::PushTry(Block* try_block) { | 9781 void Parser::PushTry(Block* try_block) { |
9999 intptr_t try_index = AllocateTryIndex(); | 9782 intptr_t try_index = AllocateTryIndex(); |
10000 try_stack_ = new (Z) TryStack(try_block, try_stack_, try_index); | 9783 try_stack_ = new (Z) TryStack(try_block, try_stack_, try_index); |
10001 } | 9784 } |
10002 | 9785 |
10003 | |
10004 Parser::TryStack* Parser::PopTry() { | 9786 Parser::TryStack* Parser::PopTry() { |
10005 TryStack* innermost_try = try_stack_; | 9787 TryStack* innermost_try = try_stack_; |
10006 try_stack_ = try_stack_->outer_try(); | 9788 try_stack_ = try_stack_->outer_try(); |
10007 return innermost_try; | 9789 return innermost_try; |
10008 } | 9790 } |
10009 | 9791 |
10010 | |
10011 void Parser::AddNodeForFinallyInlining(AstNode* node) { | 9792 void Parser::AddNodeForFinallyInlining(AstNode* node) { |
10012 if (node == NULL) { | 9793 if (node == NULL) { |
10013 return; | 9794 return; |
10014 } | 9795 } |
10015 ASSERT(node->IsReturnNode() || node->IsJumpNode()); | 9796 ASSERT(node->IsReturnNode() || node->IsJumpNode()); |
10016 const intptr_t func_level = FunctionLevel(); | 9797 const intptr_t func_level = FunctionLevel(); |
10017 TryStack* iterator = try_stack_; | 9798 TryStack* iterator = try_stack_; |
10018 while ((iterator != NULL) && | 9799 while ((iterator != NULL) && |
10019 (iterator->try_block()->scope->function_level() == func_level)) { | 9800 (iterator->try_block()->scope->function_level() == func_level)) { |
10020 // For continue and break node check if the target label is in scope. | 9801 // For continue and break node check if the target label is in scope. |
(...skipping 13 matching lines...) Expand all Loading... |
10034 // RemoveNodesForFinallyInlining below.) | 9815 // RemoveNodesForFinallyInlining below.) |
10035 if (!label->IsUnresolved() && label->owner()->IsNestedWithin(try_scope)) { | 9816 if (!label->IsUnresolved() && label->owner()->IsNestedWithin(try_scope)) { |
10036 break; | 9817 break; |
10037 } | 9818 } |
10038 } | 9819 } |
10039 iterator->AddNodeForFinallyInlining(node); | 9820 iterator->AddNodeForFinallyInlining(node); |
10040 iterator = iterator->outer_try(); | 9821 iterator = iterator->outer_try(); |
10041 } | 9822 } |
10042 } | 9823 } |
10043 | 9824 |
10044 | |
10045 void Parser::RemoveNodesForFinallyInlining(SourceLabel* label) { | 9825 void Parser::RemoveNodesForFinallyInlining(SourceLabel* label) { |
10046 TryStack* iterator = try_stack_; | 9826 TryStack* iterator = try_stack_; |
10047 const intptr_t func_level = FunctionLevel(); | 9827 const intptr_t func_level = FunctionLevel(); |
10048 while ((iterator != NULL) && | 9828 while ((iterator != NULL) && |
10049 (iterator->try_block()->scope->function_level() == func_level)) { | 9829 (iterator->try_block()->scope->function_level() == func_level)) { |
10050 iterator->RemoveJumpToLabel(label); | 9830 iterator->RemoveJumpToLabel(label); |
10051 iterator = iterator->outer_try(); | 9831 iterator = iterator->outer_try(); |
10052 } | 9832 } |
10053 } | 9833 } |
10054 | 9834 |
10055 | |
10056 // Add the inlined finally clause to the specified node. | 9835 // Add the inlined finally clause to the specified node. |
10057 void Parser::AddFinallyClauseToNode(bool is_async, | 9836 void Parser::AddFinallyClauseToNode(bool is_async, |
10058 AstNode* node, | 9837 AstNode* node, |
10059 InlinedFinallyNode* finally_clause) { | 9838 InlinedFinallyNode* finally_clause) { |
10060 ReturnNode* return_node = node->AsReturnNode(); | 9839 ReturnNode* return_node = node->AsReturnNode(); |
10061 if (return_node != NULL) { | 9840 if (return_node != NULL) { |
10062 if (FunctionLevel() == 0) { | 9841 if (FunctionLevel() == 0) { |
10063 parsed_function()->EnsureFinallyReturnTemp(is_async); | 9842 parsed_function()->EnsureFinallyReturnTemp(is_async); |
10064 } | 9843 } |
10065 return_node->AddInlinedFinallyNode(finally_clause); | 9844 return_node->AddInlinedFinallyNode(finally_clause); |
10066 return; | 9845 return; |
10067 } | 9846 } |
10068 JumpNode* jump_node = node->AsJumpNode(); | 9847 JumpNode* jump_node = node->AsJumpNode(); |
10069 ASSERT(jump_node != NULL); | 9848 ASSERT(jump_node != NULL); |
10070 jump_node->AddInlinedFinallyNode(finally_clause); | 9849 jump_node->AddInlinedFinallyNode(finally_clause); |
10071 } | 9850 } |
10072 | 9851 |
10073 | |
10074 SequenceNode* Parser::ParseCatchClauses( | 9852 SequenceNode* Parser::ParseCatchClauses( |
10075 TokenPosition handler_pos, | 9853 TokenPosition handler_pos, |
10076 bool is_async, | 9854 bool is_async, |
10077 LocalVariable* exception_var, | 9855 LocalVariable* exception_var, |
10078 LocalVariable* stack_trace_var, | 9856 LocalVariable* stack_trace_var, |
10079 LocalVariable* rethrow_exception_var, | 9857 LocalVariable* rethrow_exception_var, |
10080 LocalVariable* rethrow_stack_trace_var, | 9858 LocalVariable* rethrow_stack_trace_var, |
10081 const GrowableObjectArray& handler_types, | 9859 const GrowableObjectArray& handler_types, |
10082 bool* needs_stack_trace) { | 9860 bool* needs_stack_trace) { |
10083 // All catch blocks are merged into an if-then-else sequence of the | 9861 // All catch blocks are merged into an if-then-else sequence of the |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10265 // an outer try block is present) and code to save the exception and | 10043 // an outer try block is present) and code to save the exception and |
10266 // stack trace variables. | 10044 // stack trace variables. |
10267 // This async code is inserted before the current node sequence containing | 10045 // This async code is inserted before the current node sequence containing |
10268 // the chain of if/then/else handling all catch clauses. | 10046 // the chain of if/then/else handling all catch clauses. |
10269 async_code->Add(current); | 10047 async_code->Add(current); |
10270 current = async_code; | 10048 current = async_code; |
10271 } | 10049 } |
10272 return current; | 10050 return current; |
10273 } | 10051 } |
10274 | 10052 |
10275 | |
10276 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 10053 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
10277 const String& async_saved_try_ctx_name = String::ZoneHandle( | 10054 const String& async_saved_try_ctx_name = String::ZoneHandle( |
10278 Z, Symbols::NewFormatted(T, "%s%d", | 10055 Z, Symbols::NewFormatted(T, "%s%d", |
10279 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 10056 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
10280 last_used_try_index_ - 1)); | 10057 last_used_try_index_ - 1)); |
10281 LocalVariable* async_saved_try_ctx = | 10058 LocalVariable* async_saved_try_ctx = |
10282 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 10059 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
10283 async_saved_try_ctx_name, Object::dynamic_type()); | 10060 async_saved_try_ctx_name, Object::dynamic_type()); |
10284 ASSERT(async_temp_scope_ != NULL); | 10061 ASSERT(async_temp_scope_ != NULL); |
10285 async_temp_scope_->AddVariable(async_saved_try_ctx); | 10062 async_temp_scope_->AddVariable(async_saved_try_ctx); |
10286 ASSERT(saved_try_context != NULL); | 10063 ASSERT(saved_try_context != NULL); |
10287 current_block_->statements->Add(new (Z) StoreLocalNode( | 10064 current_block_->statements->Add(new (Z) StoreLocalNode( |
10288 TokenPosition::kNoSource, async_saved_try_ctx, | 10065 TokenPosition::kNoSource, async_saved_try_ctx, |
10289 new (Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context))); | 10066 new (Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context))); |
10290 } | 10067 } |
10291 | 10068 |
10292 | |
10293 // We create three variables for exceptions: | 10069 // We create three variables for exceptions: |
10294 // ':saved_try_context_var' - Used to save the context before the start of | 10070 // ':saved_try_context_var' - Used to save the context before the start of |
10295 // the try block. The context register is | 10071 // the try block. The context register is |
10296 // restored from this variable before | 10072 // restored from this variable before |
10297 // processing the catch block handler. | 10073 // processing the catch block handler. |
10298 // ':exception_var' - Used to save the current exception object that was | 10074 // ':exception_var' - Used to save the current exception object that was |
10299 // thrown. | 10075 // thrown. |
10300 // ':stack_trace_var' - Used to save the current stack trace object which | 10076 // ':stack_trace_var' - Used to save the current stack trace object which |
10301 // the stack trace was copied into when an exception | 10077 // the stack trace was copied into when an exception |
10302 // was thrown. | 10078 // was thrown. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10349 try_scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); | 10125 try_scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); |
10350 if (*saved_stack_trace_var == NULL) { | 10126 if (*saved_stack_trace_var == NULL) { |
10351 *saved_stack_trace_var = new (Z) | 10127 *saved_stack_trace_var = new (Z) |
10352 LocalVariable(TokenPos(), TokenPos(), Symbols::SavedStackTraceVar(), | 10128 LocalVariable(TokenPos(), TokenPos(), Symbols::SavedStackTraceVar(), |
10353 Object::dynamic_type()); | 10129 Object::dynamic_type()); |
10354 try_scope->AddVariable(*saved_stack_trace_var); | 10130 try_scope->AddVariable(*saved_stack_trace_var); |
10355 } | 10131 } |
10356 } | 10132 } |
10357 } | 10133 } |
10358 | 10134 |
10359 | |
10360 AstNode* Parser::ParseTryStatement(String* label_name) { | 10135 AstNode* Parser::ParseTryStatement(String* label_name) { |
10361 TRACE_PARSER("ParseTryStatement"); | 10136 TRACE_PARSER("ParseTryStatement"); |
10362 | 10137 |
10363 const TokenPosition try_pos = TokenPos(); | 10138 const TokenPosition try_pos = TokenPos(); |
10364 SourceLabel* try_label = NULL; | 10139 SourceLabel* try_label = NULL; |
10365 if (label_name != NULL) { | 10140 if (label_name != NULL) { |
10366 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 10141 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
10367 OpenBlock(); | 10142 OpenBlock(); |
10368 current_block_->scope->AddLabel(try_label); | 10143 current_block_->scope->AddLabel(try_label); |
10369 } | 10144 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10487 if (try_label != NULL) { | 10262 if (try_label != NULL) { |
10488 current_block_->statements->Add(try_catch_node); | 10263 current_block_->statements->Add(try_catch_node); |
10489 SequenceNode* sequence = CloseBlock(); | 10264 SequenceNode* sequence = CloseBlock(); |
10490 sequence->set_label(try_label); | 10265 sequence->set_label(try_label); |
10491 try_catch_node = sequence; | 10266 try_catch_node = sequence; |
10492 } | 10267 } |
10493 | 10268 |
10494 return try_catch_node; | 10269 return try_catch_node; |
10495 } | 10270 } |
10496 | 10271 |
10497 | |
10498 AstNode* Parser::ParseJump(String* label_name) { | 10272 AstNode* Parser::ParseJump(String* label_name) { |
10499 TRACE_PARSER("ParseJump"); | 10273 TRACE_PARSER("ParseJump"); |
10500 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 10274 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
10501 Token::Kind jump_kind = CurrentToken(); | 10275 Token::Kind jump_kind = CurrentToken(); |
10502 const TokenPosition jump_pos = TokenPos(); | 10276 const TokenPosition jump_pos = TokenPos(); |
10503 SourceLabel* target = NULL; | 10277 SourceLabel* target = NULL; |
10504 ConsumeToken(); | 10278 ConsumeToken(); |
10505 if (IsIdentifier()) { | 10279 if (IsIdentifier()) { |
10506 // Explicit label after break/continue. | 10280 // Explicit label after break/continue. |
10507 const String& target_name = *CurrentLiteral(); | 10281 const String& target_name = *CurrentLiteral(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10554 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { | 10328 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { |
10555 ReportError(jump_pos, "'break' to case clause label is illegal"); | 10329 ReportError(jump_pos, "'break' to case clause label is illegal"); |
10556 } | 10330 } |
10557 if (target->FunctionLevel() != FunctionLevel()) { | 10331 if (target->FunctionLevel() != FunctionLevel()) { |
10558 ReportError(jump_pos, "'%s' target must be in same function context", | 10332 ReportError(jump_pos, "'%s' target must be in same function context", |
10559 Token::Str(jump_kind)); | 10333 Token::Str(jump_kind)); |
10560 } | 10334 } |
10561 return new (Z) JumpNode(jump_pos, jump_kind, target); | 10335 return new (Z) JumpNode(jump_pos, jump_kind, target); |
10562 } | 10336 } |
10563 | 10337 |
10564 | |
10565 AstNode* Parser::ParseYieldStatement() { | 10338 AstNode* Parser::ParseYieldStatement() { |
10566 bool is_yield_each = false; | 10339 bool is_yield_each = false; |
10567 const TokenPosition yield_pos = TokenPos(); | 10340 const TokenPosition yield_pos = TokenPos(); |
10568 ConsumeToken(); // yield reserved word. | 10341 ConsumeToken(); // yield reserved word. |
10569 if (CurrentToken() == Token::kMUL) { | 10342 if (CurrentToken() == Token::kMUL) { |
10570 is_yield_each = true; | 10343 is_yield_each = true; |
10571 ConsumeToken(); | 10344 ConsumeToken(); |
10572 } | 10345 } |
10573 if (!innermost_function().IsGenerator() && | 10346 if (!innermost_function().IsGenerator() && |
10574 !innermost_function().IsGeneratorClosure()) { | 10347 !innermost_function().IsGeneratorClosure()) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10693 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 10466 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
10694 outer_async_saved_try_ctx))); | 10467 outer_async_saved_try_ctx))); |
10695 } | 10468 } |
10696 } else { | 10469 } else { |
10697 ASSERT(outer_saved_try_ctx == NULL); | 10470 ASSERT(outer_saved_try_ctx == NULL); |
10698 } | 10471 } |
10699 } | 10472 } |
10700 return yield; | 10473 return yield; |
10701 } | 10474 } |
10702 | 10475 |
10703 | |
10704 AstNode* Parser::ParseStatement() { | 10476 AstNode* Parser::ParseStatement() { |
10705 TRACE_PARSER("ParseStatement"); | 10477 TRACE_PARSER("ParseStatement"); |
10706 AstNode* statement = NULL; | 10478 AstNode* statement = NULL; |
10707 TokenPosition label_pos = TokenPosition::kNoSource; | 10479 TokenPosition label_pos = TokenPosition::kNoSource; |
10708 String* label_name = NULL; | 10480 String* label_name = NULL; |
10709 if (IsIdentifier()) { | 10481 if (IsIdentifier()) { |
10710 if (LookaheadToken(1) == Token::kCOLON) { | 10482 if (LookaheadToken(1) == Token::kCOLON) { |
10711 // Statement starts with a label. | 10483 // Statement starts with a label. |
10712 label_name = CurrentLiteral(); | 10484 label_name = CurrentLiteral(); |
10713 label_pos = TokenPos(); | 10485 label_pos = TokenPos(); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10881 statement = new (Z) | 10653 statement = new (Z) |
10882 ThrowNode(statement_pos, new (Z) LoadLocalNode(statement_pos, excp_var), | 10654 ThrowNode(statement_pos, new (Z) LoadLocalNode(statement_pos, excp_var), |
10883 new (Z) LoadLocalNode(statement_pos, trace_var)); | 10655 new (Z) LoadLocalNode(statement_pos, trace_var)); |
10884 } else { | 10656 } else { |
10885 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 10657 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
10886 ExpectSemicolon(); | 10658 ExpectSemicolon(); |
10887 } | 10659 } |
10888 return statement; | 10660 return statement; |
10889 } | 10661 } |
10890 | 10662 |
10891 | |
10892 void Parser::ReportError(const Error& error) { | 10663 void Parser::ReportError(const Error& error) { |
10893 Report::LongJump(error); | 10664 Report::LongJump(error); |
10894 UNREACHABLE(); | 10665 UNREACHABLE(); |
10895 } | 10666 } |
10896 | 10667 |
10897 | |
10898 void Parser::ReportErrors(const Error& prev_error, | 10668 void Parser::ReportErrors(const Error& prev_error, |
10899 const Script& script, | 10669 const Script& script, |
10900 TokenPosition token_pos, | 10670 TokenPosition token_pos, |
10901 const char* format, | 10671 const char* format, |
10902 ...) { | 10672 ...) { |
10903 va_list args; | 10673 va_list args; |
10904 va_start(args, format); | 10674 va_start(args, format); |
10905 Report::LongJumpV(prev_error, script, token_pos, format, args); | 10675 Report::LongJumpV(prev_error, script, token_pos, format, args); |
10906 va_end(args); | 10676 va_end(args); |
10907 UNREACHABLE(); | 10677 UNREACHABLE(); |
10908 } | 10678 } |
10909 | 10679 |
10910 | |
10911 void Parser::ReportError(TokenPosition token_pos, | 10680 void Parser::ReportError(TokenPosition token_pos, |
10912 const char* format, | 10681 const char* format, |
10913 ...) const { | 10682 ...) const { |
10914 va_list args; | 10683 va_list args; |
10915 va_start(args, format); | 10684 va_start(args, format); |
10916 Report::MessageV(Report::kError, script_, token_pos, Report::AtLocation, | 10685 Report::MessageV(Report::kError, script_, token_pos, Report::AtLocation, |
10917 format, args); | 10686 format, args); |
10918 va_end(args); | 10687 va_end(args); |
10919 UNREACHABLE(); | 10688 UNREACHABLE(); |
10920 } | 10689 } |
10921 | 10690 |
10922 | |
10923 void Parser::ReportErrorBefore(const char* format, ...) { | 10691 void Parser::ReportErrorBefore(const char* format, ...) { |
10924 va_list args; | 10692 va_list args; |
10925 va_start(args, format); | 10693 va_start(args, format); |
10926 Report::MessageV(Report::kError, script_, PrevTokenPos(), | 10694 Report::MessageV(Report::kError, script_, PrevTokenPos(), |
10927 Report::AfterLocation, format, args); | 10695 Report::AfterLocation, format, args); |
10928 va_end(args); | 10696 va_end(args); |
10929 UNREACHABLE(); | 10697 UNREACHABLE(); |
10930 } | 10698 } |
10931 | 10699 |
10932 | |
10933 void Parser::ReportError(const char* format, ...) const { | 10700 void Parser::ReportError(const char* format, ...) const { |
10934 va_list args; | 10701 va_list args; |
10935 va_start(args, format); | 10702 va_start(args, format); |
10936 Report::MessageV(Report::kError, script_, TokenPos(), Report::AtLocation, | 10703 Report::MessageV(Report::kError, script_, TokenPos(), Report::AtLocation, |
10937 format, args); | 10704 format, args); |
10938 va_end(args); | 10705 va_end(args); |
10939 UNREACHABLE(); | 10706 UNREACHABLE(); |
10940 } | 10707 } |
10941 | 10708 |
10942 | |
10943 void Parser::ReportWarning(TokenPosition token_pos, | 10709 void Parser::ReportWarning(TokenPosition token_pos, |
10944 const char* format, | 10710 const char* format, |
10945 ...) const { | 10711 ...) const { |
10946 va_list args; | 10712 va_list args; |
10947 va_start(args, format); | 10713 va_start(args, format); |
10948 Report::MessageV(Report::kWarning, script_, token_pos, Report::AtLocation, | 10714 Report::MessageV(Report::kWarning, script_, token_pos, Report::AtLocation, |
10949 format, args); | 10715 format, args); |
10950 va_end(args); | 10716 va_end(args); |
10951 } | 10717 } |
10952 | 10718 |
10953 | |
10954 void Parser::ReportWarning(const char* format, ...) const { | 10719 void Parser::ReportWarning(const char* format, ...) const { |
10955 va_list args; | 10720 va_list args; |
10956 va_start(args, format); | 10721 va_start(args, format); |
10957 Report::MessageV(Report::kWarning, script_, TokenPos(), Report::AtLocation, | 10722 Report::MessageV(Report::kWarning, script_, TokenPos(), Report::AtLocation, |
10958 format, args); | 10723 format, args); |
10959 va_end(args); | 10724 va_end(args); |
10960 } | 10725 } |
10961 | 10726 |
10962 | |
10963 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { | 10727 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { |
10964 if (CurrentToken() != token_expected) { | 10728 if (CurrentToken() != token_expected) { |
10965 if (msg != NULL) { | 10729 if (msg != NULL) { |
10966 ReportError("%s", msg); | 10730 ReportError("%s", msg); |
10967 } else { | 10731 } else { |
10968 ReportError("'%s' expected", Token::Str(token_expected)); | 10732 ReportError("'%s' expected", Token::Str(token_expected)); |
10969 } | 10733 } |
10970 } | 10734 } |
10971 } | 10735 } |
10972 | 10736 |
10973 | |
10974 void Parser::ExpectToken(Token::Kind token_expected) { | 10737 void Parser::ExpectToken(Token::Kind token_expected) { |
10975 if (CurrentToken() != token_expected) { | 10738 if (CurrentToken() != token_expected) { |
10976 ReportError("'%s' expected", Token::Str(token_expected)); | 10739 ReportError("'%s' expected", Token::Str(token_expected)); |
10977 } | 10740 } |
10978 ConsumeToken(); | 10741 ConsumeToken(); |
10979 } | 10742 } |
10980 | 10743 |
10981 | |
10982 void Parser::ExpectSemicolon() { | 10744 void Parser::ExpectSemicolon() { |
10983 if (CurrentToken() != Token::kSEMICOLON) { | 10745 if (CurrentToken() != Token::kSEMICOLON) { |
10984 ReportErrorBefore("semicolon expected"); | 10746 ReportErrorBefore("semicolon expected"); |
10985 } | 10747 } |
10986 ConsumeToken(); | 10748 ConsumeToken(); |
10987 } | 10749 } |
10988 | 10750 |
10989 | |
10990 void Parser::UnexpectedToken() { | 10751 void Parser::UnexpectedToken() { |
10991 ReportError("unexpected token '%s'", CurrentToken() == Token::kIDENT | 10752 ReportError("unexpected token '%s'", CurrentToken() == Token::kIDENT |
10992 ? CurrentLiteral()->ToCString() | 10753 ? CurrentLiteral()->ToCString() |
10993 : Token::Str(CurrentToken())); | 10754 : Token::Str(CurrentToken())); |
10994 } | 10755 } |
10995 | 10756 |
10996 | |
10997 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { | 10757 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { |
10998 if (CurrentToken() != Token::kIDENT) { | 10758 if (CurrentToken() != Token::kIDENT) { |
10999 ReportError("%s", msg); | 10759 ReportError("%s", msg); |
11000 } | 10760 } |
11001 String* ident = CurrentLiteral(); | 10761 String* ident = CurrentLiteral(); |
11002 if (ident->Equals("dynamic")) { | 10762 if (ident->Equals("dynamic")) { |
11003 ReportError("%s", msg); | 10763 ReportError("%s", msg); |
11004 } | 10764 } |
11005 ConsumeToken(); | 10765 ConsumeToken(); |
11006 return ident; | 10766 return ident; |
11007 } | 10767 } |
11008 | 10768 |
11009 | |
11010 // Check whether current token is an identifier or a built-in identifier. | 10769 // Check whether current token is an identifier or a built-in identifier. |
11011 String* Parser::ExpectIdentifier(const char* msg) { | 10770 String* Parser::ExpectIdentifier(const char* msg) { |
11012 if (!IsIdentifier()) { | 10771 if (!IsIdentifier()) { |
11013 ReportError("%s", msg); | 10772 ReportError("%s", msg); |
11014 } | 10773 } |
11015 String* ident = CurrentLiteral(); | 10774 String* ident = CurrentLiteral(); |
11016 ConsumeToken(); | 10775 ConsumeToken(); |
11017 return ident; | 10776 return ident; |
11018 } | 10777 } |
11019 | 10778 |
11020 | |
11021 bool Parser::IsAwaitKeyword() { | 10779 bool Parser::IsAwaitKeyword() { |
11022 return (FLAG_await_is_keyword || await_is_keyword_) && | 10780 return (FLAG_await_is_keyword || await_is_keyword_) && |
11023 IsSymbol(Symbols::Await()); | 10781 IsSymbol(Symbols::Await()); |
11024 } | 10782 } |
11025 | 10783 |
11026 | |
11027 bool Parser::IsYieldKeyword() { | 10784 bool Parser::IsYieldKeyword() { |
11028 return (FLAG_await_is_keyword || await_is_keyword_) && | 10785 return (FLAG_await_is_keyword || await_is_keyword_) && |
11029 IsSymbol(Symbols::YieldKw()); | 10786 IsSymbol(Symbols::YieldKw()); |
11030 } | 10787 } |
11031 | 10788 |
11032 | |
11033 static bool IsIncrementOperator(Token::Kind token) { | 10789 static bool IsIncrementOperator(Token::Kind token) { |
11034 return token == Token::kINCR || token == Token::kDECR; | 10790 return token == Token::kINCR || token == Token::kDECR; |
11035 } | 10791 } |
11036 | 10792 |
11037 | |
11038 static bool IsPrefixOperator(Token::Kind token) { | 10793 static bool IsPrefixOperator(Token::Kind token) { |
11039 return (token == Token::kSUB) || (token == Token::kNOT) || | 10794 return (token == Token::kSUB) || (token == Token::kNOT) || |
11040 (token == Token::kBIT_NOT); | 10795 (token == Token::kBIT_NOT); |
11041 } | 10796 } |
11042 | 10797 |
11043 | |
11044 SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos, | 10798 SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos, |
11045 AstNode* node, | 10799 AstNode* node, |
11046 LocalScope* scope) { | 10800 LocalScope* scope) { |
11047 if ((node == NULL) || !node->IsSequenceNode()) { | 10801 if ((node == NULL) || !node->IsSequenceNode()) { |
11048 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); | 10802 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); |
11049 if (node != NULL) { | 10803 if (node != NULL) { |
11050 sequence->Add(node); | 10804 sequence->Add(node); |
11051 } | 10805 } |
11052 return sequence; | 10806 return sequence; |
11053 } | 10807 } |
11054 return node->AsSequenceNode(); | 10808 return node->AsSequenceNode(); |
11055 } | 10809 } |
11056 | 10810 |
11057 | |
11058 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10811 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
11059 AstNode* Parser::ThrowTypeError(TokenPosition type_pos, | 10812 AstNode* Parser::ThrowTypeError(TokenPosition type_pos, |
11060 const AbstractType& type, | 10813 const AbstractType& type, |
11061 LibraryPrefix* prefix) { | 10814 LibraryPrefix* prefix) { |
11062 ArgumentListNode* arguments = new (Z) ArgumentListNode(type_pos); | 10815 ArgumentListNode* arguments = new (Z) ArgumentListNode(type_pos); |
11063 | 10816 |
11064 String& method_name = String::Handle(Z); | 10817 String& method_name = String::Handle(Z); |
11065 if (prefix == NULL) { | 10818 if (prefix == NULL) { |
11066 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | 10819 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); |
11067 } else { | 10820 } else { |
11068 arguments->Add(new (Z) LiteralNode(type_pos, *prefix)); | 10821 arguments->Add(new (Z) LiteralNode(type_pos, *prefix)); |
11069 method_name = | 10822 method_name = |
11070 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw(); | 10823 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw(); |
11071 } | 10824 } |
11072 // Location argument. | 10825 // Location argument. |
11073 arguments->Add(new (Z) LiteralNode( | 10826 arguments->Add(new (Z) LiteralNode( |
11074 type_pos, | 10827 type_pos, |
11075 Integer::ZoneHandle(Z, Integer::New(type_pos.value(), Heap::kOld)))); | 10828 Integer::ZoneHandle(Z, Integer::New(type_pos.value(), Heap::kOld)))); |
11076 // Src value argument. | 10829 // Src value argument. |
11077 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); | 10830 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); |
11078 // Dst type argument. | 10831 // Dst type argument. |
11079 arguments->Add(new (Z) LiteralNode(type_pos, type)); | 10832 arguments->Add(new (Z) LiteralNode(type_pos, type)); |
11080 // Dst name argument. | 10833 // Dst name argument. |
11081 arguments->Add(new (Z) LiteralNode(type_pos, Symbols::Empty())); | 10834 arguments->Add(new (Z) LiteralNode(type_pos, Symbols::Empty())); |
11082 // Bound error msg argument. | 10835 // Bound error msg argument. |
11083 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); | 10836 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); |
11084 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); | 10837 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); |
11085 } | 10838 } |
11086 | 10839 |
11087 | |
11088 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10840 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
11089 AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos, | 10841 AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos, |
11090 const Class& cls, | 10842 const Class& cls, |
11091 const String& function_name, | 10843 const String& function_name, |
11092 ArgumentListNode* function_arguments, | 10844 ArgumentListNode* function_arguments, |
11093 InvocationMirror::Call im_call, | 10845 InvocationMirror::Call im_call, |
11094 InvocationMirror::Type im_type, | 10846 InvocationMirror::Type im_type, |
11095 const Function* func, | 10847 const Function* func, |
11096 const LibraryPrefix* prefix) { | 10848 const LibraryPrefix* prefix) { |
11097 ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos); | 10849 ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11171 // between dart2js and VM. Update the constructor to accept a string | 10923 // between dart2js and VM. Update the constructor to accept a string |
11172 // describing the formal parameters of an incompatible call target. | 10924 // describing the formal parameters of an incompatible call target. |
11173 array = Array::New(1, Heap::kOld); | 10925 array = Array::New(1, Heap::kOld); |
11174 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); | 10926 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); |
11175 } | 10927 } |
11176 arguments->Add(new (Z) LiteralNode(call_pos, array)); | 10928 arguments->Add(new (Z) LiteralNode(call_pos, array)); |
11177 | 10929 |
11178 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); | 10930 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); |
11179 } | 10931 } |
11180 | 10932 |
11181 | |
11182 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 10933 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
11183 TRACE_PARSER("ParseBinaryExpr"); | 10934 TRACE_PARSER("ParseBinaryExpr"); |
11184 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10935 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
11185 AstNode* left_operand = ParseUnaryExpr(); | 10936 AstNode* left_operand = ParseUnaryExpr(); |
11186 if (left_operand->IsPrimaryNode() && | 10937 if (left_operand->IsPrimaryNode() && |
11187 (left_operand->AsPrimaryNode()->IsSuper())) { | 10938 (left_operand->AsPrimaryNode()->IsSuper())) { |
11188 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10939 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
11189 } | 10940 } |
11190 int current_preced = Token::Precedence(CurrentToken()); | 10941 int current_preced = Token::Precedence(CurrentToken()); |
11191 while (current_preced >= min_preced) { | 10942 while (current_preced >= min_preced) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11234 } else { | 10985 } else { |
11235 left_operand = | 10986 left_operand = |
11236 OptimizeBinaryOpNode(op_pos, op_kind, left_operand, right_operand); | 10987 OptimizeBinaryOpNode(op_pos, op_kind, left_operand, right_operand); |
11237 } | 10988 } |
11238 } | 10989 } |
11239 current_preced--; | 10990 current_preced--; |
11240 } | 10991 } |
11241 return left_operand; | 10992 return left_operand; |
11242 } | 10993 } |
11243 | 10994 |
11244 | |
11245 AstNode* Parser::ParseAwaitableExprList() { | 10995 AstNode* Parser::ParseAwaitableExprList() { |
11246 TRACE_PARSER("ParseAwaitableExprList"); | 10996 TRACE_PARSER("ParseAwaitableExprList"); |
11247 SequenceNode* preamble = NULL; | 10997 SequenceNode* preamble = NULL; |
11248 AstNode* expressions = | 10998 AstNode* expressions = |
11249 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); | 10999 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); |
11250 if (preamble != NULL) { | 11000 if (preamble != NULL) { |
11251 preamble->Add(expressions); | 11001 preamble->Add(expressions); |
11252 expressions = preamble; | 11002 expressions = preamble; |
11253 } | 11003 } |
11254 if (CurrentToken() == Token::kCOMMA) { | 11004 if (CurrentToken() == Token::kCOMMA) { |
11255 // Collect comma-separated expressions in a non scope owning sequence node. | 11005 // Collect comma-separated expressions in a non scope owning sequence node. |
11256 SequenceNode* list = new (Z) SequenceNode(TokenPos(), NULL); | 11006 SequenceNode* list = new (Z) SequenceNode(TokenPos(), NULL); |
11257 list->Add(expressions); | 11007 list->Add(expressions); |
11258 while (CurrentToken() == Token::kCOMMA) { | 11008 while (CurrentToken() == Token::kCOMMA) { |
11259 ConsumeToken(); | 11009 ConsumeToken(); |
11260 preamble = NULL; | 11010 preamble = NULL; |
11261 AstNode* expr = | 11011 AstNode* expr = |
11262 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); | 11012 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); |
11263 if (preamble != NULL) { | 11013 if (preamble != NULL) { |
11264 list->Add(preamble); | 11014 list->Add(preamble); |
11265 } | 11015 } |
11266 list->Add(expr); | 11016 list->Add(expr); |
11267 } | 11017 } |
11268 expressions = list; | 11018 expressions = list; |
11269 } | 11019 } |
11270 return expressions; | 11020 return expressions; |
11271 } | 11021 } |
11272 | 11022 |
11273 | |
11274 void Parser::EnsureExpressionTemp() { | 11023 void Parser::EnsureExpressionTemp() { |
11275 // Temporary used later by the flow_graph_builder. | 11024 // Temporary used later by the flow_graph_builder. |
11276 parsed_function()->EnsureExpressionTemp(); | 11025 parsed_function()->EnsureExpressionTemp(); |
11277 } | 11026 } |
11278 | 11027 |
11279 | |
11280 LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos, | 11028 LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos, |
11281 const char* s) { | 11029 const char* s) { |
11282 char name[64]; | 11030 char name[64]; |
11283 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); | 11031 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); |
11284 LocalVariable* temp = new (Z) LocalVariable( | 11032 LocalVariable* temp = new (Z) LocalVariable( |
11285 token_pos, token_pos, String::ZoneHandle(Z, Symbols::New(T, name)), | 11033 token_pos, token_pos, String::ZoneHandle(Z, Symbols::New(T, name)), |
11286 Object::dynamic_type()); | 11034 Object::dynamic_type()); |
11287 temp->set_is_final(); | 11035 temp->set_is_final(); |
11288 current_block_->scope->AddVariable(temp); | 11036 current_block_->scope->AddVariable(temp); |
11289 return temp; | 11037 return temp; |
11290 } | 11038 } |
11291 | 11039 |
11292 | |
11293 AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos, | 11040 AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos, |
11294 Token::Kind binary_op, | 11041 Token::Kind binary_op, |
11295 AstNode* lhs, | 11042 AstNode* lhs, |
11296 AstNode* rhs) { | 11043 AstNode* rhs) { |
11297 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 11044 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
11298 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 11045 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
11299 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 11046 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
11300 if (lhs_literal->literal().IsDouble() && | 11047 if (lhs_literal->literal().IsDouble() && |
11301 rhs_literal->literal().IsDouble()) { | 11048 rhs_literal->literal().IsDouble()) { |
11302 double left_double = Double::Cast(lhs_literal->literal()).value(); | 11049 double left_double = Double::Cast(lhs_literal->literal()).value(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11337 LoadLocalNode* load_left_temp = new (Z) LoadLocalNode(no_pos, left_temp); | 11084 LoadLocalNode* load_left_temp = new (Z) LoadLocalNode(no_pos, left_temp); |
11338 ComparisonNode* null_compare = new (Z) | 11085 ComparisonNode* null_compare = new (Z) |
11339 ComparisonNode(no_pos, Token::kNE_STRICT, load_left_temp, null_operand); | 11086 ComparisonNode(no_pos, Token::kNE_STRICT, load_left_temp, null_operand); |
11340 result->AddNode( | 11087 result->AddNode( |
11341 new (Z) ConditionalExprNode(op_pos, null_compare, load_left_temp, rhs)); | 11088 new (Z) ConditionalExprNode(op_pos, null_compare, load_left_temp, rhs)); |
11342 return result; | 11089 return result; |
11343 } | 11090 } |
11344 return new (Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 11091 return new (Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
11345 } | 11092 } |
11346 | 11093 |
11347 | |
11348 AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos, | 11094 AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos, |
11349 Token::Kind assignment_op, | 11095 Token::Kind assignment_op, |
11350 AstNode* lhs, | 11096 AstNode* lhs, |
11351 AstNode* rhs) { | 11097 AstNode* rhs) { |
11352 TRACE_PARSER("ExpandAssignableOp"); | 11098 TRACE_PARSER("ExpandAssignableOp"); |
11353 switch (assignment_op) { | 11099 switch (assignment_op) { |
11354 case Token::kASSIGN: | 11100 case Token::kASSIGN: |
11355 return rhs; | 11101 return rhs; |
11356 case Token::kASSIGN_ADD: | 11102 case Token::kASSIGN_ADD: |
11357 return new (Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 11103 return new (Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
(...skipping 21 matching lines...) Expand all Loading... |
11379 return new (Z) BinaryOpNode(op_pos, Token::kIFNULL, lhs, rhs); | 11125 return new (Z) BinaryOpNode(op_pos, Token::kIFNULL, lhs, rhs); |
11380 default: | 11126 default: |
11381 ReportError(op_pos, | 11127 ReportError(op_pos, |
11382 "internal error: ExpandAssignableOp '%s' unimplemented", | 11128 "internal error: ExpandAssignableOp '%s' unimplemented", |
11383 Token::Name(assignment_op)); | 11129 Token::Name(assignment_op)); |
11384 UNIMPLEMENTED(); | 11130 UNIMPLEMENTED(); |
11385 return NULL; | 11131 return NULL; |
11386 } | 11132 } |
11387 } | 11133 } |
11388 | 11134 |
11389 | |
11390 // Evaluates the value of the compile time constant expression | 11135 // Evaluates the value of the compile time constant expression |
11391 // and returns a literal node for the value. | 11136 // and returns a literal node for the value. |
11392 LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) { | 11137 LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) { |
11393 if (expr->IsLiteralNode()) { | 11138 if (expr->IsLiteralNode()) { |
11394 return expr->AsLiteralNode(); | 11139 return expr->AsLiteralNode(); |
11395 } | 11140 } |
11396 if (expr->EvalConstExpr() == NULL) { | 11141 if (expr->EvalConstExpr() == NULL) { |
11397 ReportError(expr_pos, "expression is not a valid compile-time constant"); | 11142 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
11398 } | 11143 } |
11399 return new (Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr)); | 11144 return new (Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr)); |
11400 } | 11145 } |
11401 | 11146 |
11402 | |
11403 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 11147 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
11404 AstNode* node = *expr; | 11148 AstNode* node = *expr; |
11405 TokenPosition token_pos = node->token_pos(); | 11149 TokenPosition token_pos = node->token_pos(); |
11406 LetNode* result = new (Z) LetNode(token_pos); | 11150 LetNode* result = new (Z) LetNode(token_pos); |
11407 if (node->IsLoadIndexedNode()) { | 11151 if (node->IsLoadIndexedNode()) { |
11408 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 11152 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
11409 AstNode* array = load_indexed->array(); | 11153 AstNode* array = load_indexed->array(); |
11410 AstNode* index = load_indexed->index_expr(); | 11154 AstNode* index = load_indexed->index_expr(); |
11411 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 11155 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
11412 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 11156 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
(...skipping 14 matching lines...) Expand all Loading... |
11427 LocalVariable* t0 = result->AddInitializer(getter->receiver()); | 11171 LocalVariable* t0 = result->AddInitializer(getter->receiver()); |
11428 receiver = new (Z) LoadLocalNode(token_pos, t0); | 11172 receiver = new (Z) LoadLocalNode(token_pos, t0); |
11429 } | 11173 } |
11430 *expr = new (Z) InstanceGetterNode( | 11174 *expr = new (Z) InstanceGetterNode( |
11431 token_pos, receiver, getter->field_name(), getter->is_conditional()); | 11175 token_pos, receiver, getter->field_name(), getter->is_conditional()); |
11432 return result; | 11176 return result; |
11433 } | 11177 } |
11434 return result; | 11178 return result; |
11435 } | 11179 } |
11436 | 11180 |
11437 | |
11438 // Check whether the syntax of expression expr is a grammatically legal | 11181 // Check whether the syntax of expression expr is a grammatically legal |
11439 // assignable expression. This check is used to detect situations where | 11182 // assignable expression. This check is used to detect situations where |
11440 // the expression itself is assignable, but the source is grammatically | 11183 // the expression itself is assignable, but the source is grammatically |
11441 // wrong. The AST representation of an expression cannot distinguish | 11184 // wrong. The AST representation of an expression cannot distinguish |
11442 // between x = 0 and (x) = 0. The latter is illegal. | 11185 // between x = 0 and (x) = 0. The latter is illegal. |
11443 // A syntactically legal assignable expression always ends with an | 11186 // A syntactically legal assignable expression always ends with an |
11444 // identifier token or a ] token. We rewind the token iterator and | 11187 // identifier token or a ] token. We rewind the token iterator and |
11445 // check whether the token before end_pos is an identifier or ]. | 11188 // check whether the token before end_pos is an identifier or ]. |
11446 bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos) { | 11189 bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos) { |
11447 ASSERT(expr->token_pos().IsReal()); | 11190 ASSERT(expr->token_pos().IsReal()); |
11448 ASSERT(expr->token_pos() < end_pos); | 11191 ASSERT(expr->token_pos() < end_pos); |
11449 SetPosition(expr->token_pos()); | 11192 SetPosition(expr->token_pos()); |
11450 Token::Kind token = Token::kILLEGAL; | 11193 Token::Kind token = Token::kILLEGAL; |
11451 while (TokenPos() < end_pos) { | 11194 while (TokenPos() < end_pos) { |
11452 token = CurrentToken(); | 11195 token = CurrentToken(); |
11453 ConsumeToken(); | 11196 ConsumeToken(); |
11454 } | 11197 } |
11455 ASSERT(TokenPos() == end_pos); | 11198 ASSERT(TokenPos() == end_pos); |
11456 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 11199 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
11457 } | 11200 } |
11458 | 11201 |
11459 | |
11460 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 11202 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
11461 AstNode* rhs, | 11203 AstNode* rhs, |
11462 const String* left_ident, | 11204 const String* left_ident, |
11463 TokenPosition left_pos, | 11205 TokenPosition left_pos, |
11464 bool is_compound /* = false */) { | 11206 bool is_compound /* = false */) { |
11465 AstNode* result = original->MakeAssignmentNode(rhs); | 11207 AstNode* result = original->MakeAssignmentNode(rhs); |
11466 if (result == NULL) { | 11208 if (result == NULL) { |
11467 String& name = String::ZoneHandle(Z); | 11209 String& name = String::ZoneHandle(Z); |
11468 const Class* target_cls = ¤t_class(); | 11210 const Class* target_cls = ¤t_class(); |
11469 if (original->IsTypeNode()) { | 11211 if (original->IsTypeNode()) { |
(...skipping 30 matching lines...) Expand all Loading... |
11500 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { | 11242 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { |
11501 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); | 11243 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); |
11502 AstNode* modified_assign = | 11244 AstNode* modified_assign = |
11503 CreateAssignmentNode(original, ifnull->right(), left_ident, left_pos); | 11245 CreateAssignmentNode(original, ifnull->right(), left_ident, left_pos); |
11504 result = OptimizeBinaryOpNode(ifnull->token_pos(), ifnull->kind(), | 11246 result = OptimizeBinaryOpNode(ifnull->token_pos(), ifnull->kind(), |
11505 ifnull->left(), modified_assign); | 11247 ifnull->left(), modified_assign); |
11506 } | 11248 } |
11507 return result; | 11249 return result; |
11508 } | 11250 } |
11509 | 11251 |
11510 | |
11511 AstNode* Parser::ParseCascades(AstNode* expr) { | 11252 AstNode* Parser::ParseCascades(AstNode* expr) { |
11512 TokenPosition cascade_pos = TokenPos(); | 11253 TokenPosition cascade_pos = TokenPos(); |
11513 LetNode* cascade = new (Z) LetNode(cascade_pos); | 11254 LetNode* cascade = new (Z) LetNode(cascade_pos); |
11514 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 11255 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
11515 while (CurrentToken() == Token::kCASCADE) { | 11256 while (CurrentToken() == Token::kCASCADE) { |
11516 cascade_pos = TokenPos(); | 11257 cascade_pos = TokenPos(); |
11517 LoadLocalNode* load_cascade_receiver = | 11258 LoadLocalNode* load_cascade_receiver = |
11518 new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var); | 11259 new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var); |
11519 if (Token::IsIdentifier(LookaheadToken(1))) { | 11260 if (Token::IsIdentifier(LookaheadToken(1))) { |
11520 // Replace .. with . for ParseSelectors(). | 11261 // Replace .. with . for ParseSelectors(). |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11557 } | 11298 } |
11558 } | 11299 } |
11559 cascade->AddNode(expr); | 11300 cascade->AddNode(expr); |
11560 } | 11301 } |
11561 // The result is an expression with the (side effects of the) cascade | 11302 // The result is an expression with the (side effects of the) cascade |
11562 // sequence followed by the (value of the) receiver temp variable load. | 11303 // sequence followed by the (value of the) receiver temp variable load. |
11563 cascade->AddNode(new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); | 11304 cascade->AddNode(new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); |
11564 return cascade; | 11305 return cascade; |
11565 } | 11306 } |
11566 | 11307 |
11567 | |
11568 // Convert loading of a static const field into a literal node. | 11308 // Convert loading of a static const field into a literal node. |
11569 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { | 11309 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { |
11570 if (expr->IsLoadStaticFieldNode()) { | 11310 if (expr->IsLoadStaticFieldNode()) { |
11571 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 11311 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
11572 if (field.is_const() && | 11312 if (field.is_const() && |
11573 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { | 11313 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { |
11574 ASSERT(field.StaticValue() != Object::sentinel().raw()); | 11314 ASSERT(field.StaticValue() != Object::sentinel().raw()); |
11575 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); | 11315 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); |
11576 return new (zone) LiteralNode( | 11316 return new (zone) LiteralNode( |
11577 expr->token_pos(), Instance::ZoneHandle(zone, field.StaticValue())); | 11317 expr->token_pos(), Instance::ZoneHandle(zone, field.StaticValue())); |
11578 } | 11318 } |
11579 } | 11319 } |
11580 return expr; | 11320 return expr; |
11581 } | 11321 } |
11582 | 11322 |
11583 | |
11584 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, | 11323 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, |
11585 bool consume_cascades, | 11324 bool consume_cascades, |
11586 SequenceNode** await_preamble) { | 11325 SequenceNode** await_preamble) { |
11587 TRACE_PARSER("ParseAwaitableExpr"); | 11326 TRACE_PARSER("ParseAwaitableExpr"); |
11588 BoolScope saved_seen_await(&parsed_function()->have_seen_await_expr_, false); | 11327 BoolScope saved_seen_await(&parsed_function()->have_seen_await_expr_, false); |
11589 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 11328 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
11590 if (parsed_function()->have_seen_await()) { | 11329 if (parsed_function()->have_seen_await()) { |
11591 // Make sure we do not reuse the scope to avoid creating contexts that we | 11330 // Make sure we do not reuse the scope to avoid creating contexts that we |
11592 // are unaware of, i.e, creating contexts that have already been covered. | 11331 // are unaware of, i.e, creating contexts that have already been covered. |
11593 // See FlowGraphBuilder::VisitSequenceNode() for details on when contexts | 11332 // See FlowGraphBuilder::VisitSequenceNode() for details on when contexts |
11594 // are created. | 11333 // are created. |
11595 OpenBlock(); | 11334 OpenBlock(); |
11596 AwaitTransformer at(current_block_->statements, async_temp_scope_); | 11335 AwaitTransformer at(current_block_->statements, async_temp_scope_); |
11597 AstNode* result = at.Transform(expr); | 11336 AstNode* result = at.Transform(expr); |
11598 SequenceNode* preamble = CloseBlock(); | 11337 SequenceNode* preamble = CloseBlock(); |
11599 if (await_preamble == NULL) { | 11338 if (await_preamble == NULL) { |
11600 current_block_->statements->Add(preamble); | 11339 current_block_->statements->Add(preamble); |
11601 } else { | 11340 } else { |
11602 *await_preamble = preamble; | 11341 *await_preamble = preamble; |
11603 } | 11342 } |
11604 return result; | 11343 return result; |
11605 } | 11344 } |
11606 return expr; | 11345 return expr; |
11607 } | 11346 } |
11608 | 11347 |
11609 | |
11610 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 11348 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
11611 bool consume_cascades) { | 11349 bool consume_cascades) { |
11612 TRACE_PARSER("ParseExpr"); | 11350 TRACE_PARSER("ParseExpr"); |
11613 String* expr_ident = | 11351 String* expr_ident = |
11614 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11352 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11615 const TokenPosition expr_pos = TokenPos(); | 11353 const TokenPosition expr_pos = TokenPos(); |
11616 | 11354 |
11617 RecursionChecker rc(this); | 11355 RecursionChecker rc(this); |
11618 | 11356 |
11619 if (CurrentToken() == Token::kTHROW) { | 11357 if (CurrentToken() == Token::kTHROW) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11674 return let_expr; | 11412 return let_expr; |
11675 } else { | 11413 } else { |
11676 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); | 11414 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
11677 AstNode* assign_expr = | 11415 AstNode* assign_expr = |
11678 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 11416 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
11679 ASSERT(assign_expr != NULL); | 11417 ASSERT(assign_expr != NULL); |
11680 return assign_expr; | 11418 return assign_expr; |
11681 } | 11419 } |
11682 } | 11420 } |
11683 | 11421 |
11684 | |
11685 LiteralNode* Parser::ParseConstExpr() { | 11422 LiteralNode* Parser::ParseConstExpr() { |
11686 TRACE_PARSER("ParseConstExpr"); | 11423 TRACE_PARSER("ParseConstExpr"); |
11687 TokenPosition expr_pos = TokenPos(); | 11424 TokenPosition expr_pos = TokenPos(); |
11688 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 11425 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
11689 if (!expr->IsLiteralNode()) { | 11426 if (!expr->IsLiteralNode()) { |
11690 ReportError(expr_pos, "expression must be a compile-time constant"); | 11427 ReportError(expr_pos, "expression must be a compile-time constant"); |
11691 } | 11428 } |
11692 return expr->AsLiteralNode(); | 11429 return expr->AsLiteralNode(); |
11693 } | 11430 } |
11694 | 11431 |
11695 | |
11696 AstNode* Parser::ParseConditionalExpr() { | 11432 AstNode* Parser::ParseConditionalExpr() { |
11697 TRACE_PARSER("ParseConditionalExpr"); | 11433 TRACE_PARSER("ParseConditionalExpr"); |
11698 const TokenPosition expr_pos = TokenPos(); | 11434 const TokenPosition expr_pos = TokenPos(); |
11699 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); | 11435 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); |
11700 if (CurrentToken() == Token::kCONDITIONAL) { | 11436 if (CurrentToken() == Token::kCONDITIONAL) { |
11701 EnsureExpressionTemp(); | 11437 EnsureExpressionTemp(); |
11702 ConsumeToken(); | 11438 ConsumeToken(); |
11703 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 11439 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
11704 ExpectToken(Token::kCOLON); | 11440 ExpectToken(Token::kCOLON); |
11705 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 11441 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
11706 expr = new (Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 11442 expr = new (Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
11707 } | 11443 } |
11708 return expr; | 11444 return expr; |
11709 } | 11445 } |
11710 | 11446 |
11711 | |
11712 AstNode* Parser::ParseUnaryExpr() { | 11447 AstNode* Parser::ParseUnaryExpr() { |
11713 TRACE_PARSER("ParseUnaryExpr"); | 11448 TRACE_PARSER("ParseUnaryExpr"); |
11714 AstNode* expr = NULL; | 11449 AstNode* expr = NULL; |
11715 const TokenPosition op_pos = TokenPos(); | 11450 const TokenPosition op_pos = TokenPos(); |
11716 if (IsAwaitKeyword()) { | 11451 if (IsAwaitKeyword()) { |
11717 TRACE_PARSER("ParseAwaitExpr"); | 11452 TRACE_PARSER("ParseAwaitExpr"); |
11718 if (!innermost_function().IsAsyncFunction() && | 11453 if (!innermost_function().IsAsyncFunction() && |
11719 !innermost_function().IsAsyncClosure() && | 11454 !innermost_function().IsAsyncClosure() && |
11720 !innermost_function().IsAsyncGenerator() && | 11455 !innermost_function().IsAsyncGenerator() && |
11721 !innermost_function().IsAsyncGenClosure()) { | 11456 !innermost_function().IsAsyncGenClosure()) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11766 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); | 11501 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); |
11767 ASSERT(store != NULL); | 11502 ASSERT(store != NULL); |
11768 let_expr->AddNode(store); | 11503 let_expr->AddNode(store); |
11769 expr = let_expr; | 11504 expr = let_expr; |
11770 } else { | 11505 } else { |
11771 expr = ParsePostfixExpr(); | 11506 expr = ParsePostfixExpr(); |
11772 } | 11507 } |
11773 return expr; | 11508 return expr; |
11774 } | 11509 } |
11775 | 11510 |
11776 | |
11777 ArgumentListNode* Parser::ParseActualParameters( | 11511 ArgumentListNode* Parser::ParseActualParameters( |
11778 ArgumentListNode* implicit_arguments, | 11512 ArgumentListNode* implicit_arguments, |
11779 const TypeArguments& func_type_args, | 11513 const TypeArguments& func_type_args, |
11780 bool require_const) { | 11514 bool require_const) { |
11781 TRACE_PARSER("ParseActualParameters"); | 11515 TRACE_PARSER("ParseActualParameters"); |
11782 ASSERT(CurrentToken() == Token::kLPAREN); | 11516 ASSERT(CurrentToken() == Token::kLPAREN); |
11783 const bool saved_mode = SetAllowFunctionLiterals(true); | 11517 const bool saved_mode = SetAllowFunctionLiterals(true); |
11784 ArgumentListNode* arguments; | 11518 ArgumentListNode* arguments; |
11785 if (implicit_arguments == NULL) { | 11519 if (implicit_arguments == NULL) { |
11786 // TODO(regis): When require_const is true, do we need to check that | 11520 // TODO(regis): When require_const is true, do we need to check that |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11828 ConsumeToken(); | 11562 ConsumeToken(); |
11829 } | 11563 } |
11830 ExpectToken(Token::kRPAREN); | 11564 ExpectToken(Token::kRPAREN); |
11831 SetAllowFunctionLiterals(saved_mode); | 11565 SetAllowFunctionLiterals(saved_mode); |
11832 if (named_argument_seen) { | 11566 if (named_argument_seen) { |
11833 arguments->set_names(Array::Handle(Z, Array::MakeFixedLength(names))); | 11567 arguments->set_names(Array::Handle(Z, Array::MakeFixedLength(names))); |
11834 } | 11568 } |
11835 return arguments; | 11569 return arguments; |
11836 } | 11570 } |
11837 | 11571 |
11838 | |
11839 AstNode* Parser::ParseStaticCall(const Class& cls, | 11572 AstNode* Parser::ParseStaticCall(const Class& cls, |
11840 const String& func_name, | 11573 const String& func_name, |
11841 TokenPosition ident_pos, | 11574 TokenPosition ident_pos, |
11842 const TypeArguments& func_type_args, | 11575 const TypeArguments& func_type_args, |
11843 const LibraryPrefix* prefix) { | 11576 const LibraryPrefix* prefix) { |
11844 TRACE_PARSER("ParseStaticCall"); | 11577 TRACE_PARSER("ParseStaticCall"); |
11845 const TokenPosition call_pos = TokenPos(); | 11578 const TokenPosition call_pos = TokenPos(); |
11846 ASSERT(CurrentToken() == Token::kLPAREN); | 11579 ASSERT(CurrentToken() == Token::kLPAREN); |
11847 ArgumentListNode* arguments = | 11580 ArgumentListNode* arguments = |
11848 ParseActualParameters(NULL, func_type_args, kAllowConst); | 11581 ParseActualParameters(NULL, func_type_args, kAllowConst); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11907 1, new (Z) LiteralNode(arg1->token_pos(), | 11640 1, new (Z) LiteralNode(arg1->token_pos(), |
11908 EvaluateConstExpr(arg1->token_pos(), arg1))); | 11641 EvaluateConstExpr(arg1->token_pos(), arg1))); |
11909 } | 11642 } |
11910 } | 11643 } |
11911 return new (Z) ComparisonNode(ident_pos, Token::kEQ_STRICT, | 11644 return new (Z) ComparisonNode(ident_pos, Token::kEQ_STRICT, |
11912 arguments->NodeAt(0), arguments->NodeAt(1)); | 11645 arguments->NodeAt(0), arguments->NodeAt(1)); |
11913 } | 11646 } |
11914 return new (Z) StaticCallNode(ident_pos, func, arguments); | 11647 return new (Z) StaticCallNode(ident_pos, func, arguments); |
11915 } | 11648 } |
11916 | 11649 |
11917 | |
11918 AstNode* Parser::ParseInstanceCall(AstNode* receiver, | 11650 AstNode* Parser::ParseInstanceCall(AstNode* receiver, |
11919 const String& func_name, | 11651 const String& func_name, |
11920 TokenPosition ident_pos, | 11652 TokenPosition ident_pos, |
11921 const TypeArguments& func_type_args, | 11653 const TypeArguments& func_type_args, |
11922 bool is_conditional) { | 11654 bool is_conditional) { |
11923 TRACE_PARSER("ParseInstanceCall"); | 11655 TRACE_PARSER("ParseInstanceCall"); |
11924 CheckToken(Token::kLPAREN); | 11656 CheckToken(Token::kLPAREN); |
11925 ArgumentListNode* arguments = | 11657 ArgumentListNode* arguments = |
11926 ParseActualParameters(NULL, func_type_args, kAllowConst); | 11658 ParseActualParameters(NULL, func_type_args, kAllowConst); |
11927 return new (Z) InstanceCallNode(ident_pos, receiver, func_name, arguments, | 11659 return new (Z) InstanceCallNode(ident_pos, receiver, func_name, arguments, |
11928 is_conditional); | 11660 is_conditional); |
11929 } | 11661 } |
11930 | 11662 |
11931 | |
11932 AstNode* Parser::ParseClosureCall(AstNode* closure, | 11663 AstNode* Parser::ParseClosureCall(AstNode* closure, |
11933 const TypeArguments& func_type_args) { | 11664 const TypeArguments& func_type_args) { |
11934 TRACE_PARSER("ParseClosureCall"); | 11665 TRACE_PARSER("ParseClosureCall"); |
11935 const TokenPosition call_pos = TokenPos(); | 11666 const TokenPosition call_pos = TokenPos(); |
11936 ASSERT(CurrentToken() == Token::kLPAREN); | 11667 ASSERT(CurrentToken() == Token::kLPAREN); |
11937 ArgumentListNode* arguments = | 11668 ArgumentListNode* arguments = |
11938 ParseActualParameters(NULL, func_type_args, kAllowConst); | 11669 ParseActualParameters(NULL, func_type_args, kAllowConst); |
11939 return BuildClosureCall(call_pos, closure, arguments); | 11670 return BuildClosureCall(call_pos, closure, arguments); |
11940 } | 11671 } |
11941 | 11672 |
11942 | |
11943 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 11673 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
11944 TokenPosition ident_pos) { | 11674 TokenPosition ident_pos) { |
11945 // If the static field has an initializer, initialize the field at compile | 11675 // If the static field has an initializer, initialize the field at compile |
11946 // time, which is only possible if the field is const. | 11676 // time, which is only possible if the field is const. |
11947 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 11677 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
11948 if (initializing_getter != NULL) { | 11678 if (initializing_getter != NULL) { |
11949 // The field is not yet initialized and could not be initialized at compile | 11679 // The field is not yet initialized and could not be initialized at compile |
11950 // time. The getter will initialize the field. | 11680 // time. The getter will initialize the field. |
11951 return initializing_getter; | 11681 return initializing_getter; |
11952 } | 11682 } |
(...skipping 10 matching lines...) Expand all Loading... |
11963 return new (Z) | 11693 return new (Z) |
11964 LoadStaticFieldNode(ident_pos, Field::ZoneHandle(Z, field.raw())); | 11694 LoadStaticFieldNode(ident_pos, Field::ZoneHandle(Z, field.raw())); |
11965 } else { | 11695 } else { |
11966 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); | 11696 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); |
11967 return new (Z) StaticGetterNode(ident_pos, | 11697 return new (Z) StaticGetterNode(ident_pos, |
11968 NULL, // Receiver. | 11698 NULL, // Receiver. |
11969 field_owner, field_name); | 11699 field_owner, field_name); |
11970 } | 11700 } |
11971 } | 11701 } |
11972 | 11702 |
11973 | |
11974 // Reference to 'field_name' with explicit class as primary. | 11703 // Reference to 'field_name' with explicit class as primary. |
11975 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, | 11704 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, |
11976 const String& field_name, | 11705 const String& field_name, |
11977 TokenPosition ident_pos) { | 11706 TokenPosition ident_pos) { |
11978 AstNode* access = NULL; | 11707 AstNode* access = NULL; |
11979 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); | 11708 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); |
11980 Function& func = Function::ZoneHandle(Z); | 11709 Function& func = Function::ZoneHandle(Z); |
11981 if (field.IsNull()) { | 11710 if (field.IsNull()) { |
11982 // No field, check if we have an explicit getter function. | 11711 // No field, check if we have an explicit getter function. |
11983 func = cls.LookupGetterFunction(field_name); | 11712 func = cls.LookupGetterFunction(field_name); |
(...skipping 16 matching lines...) Expand all Loading... |
12000 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 11729 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
12001 access = new (Z) StaticGetterNode( | 11730 access = new (Z) StaticGetterNode( |
12002 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), field_name); | 11731 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), field_name); |
12003 } | 11732 } |
12004 } else { | 11733 } else { |
12005 access = GenerateStaticFieldLookup(field, ident_pos); | 11734 access = GenerateStaticFieldLookup(field, ident_pos); |
12006 } | 11735 } |
12007 return access; | 11736 return access; |
12008 } | 11737 } |
12009 | 11738 |
12010 | |
12011 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 11739 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
12012 if (!node->IsPrimaryNode()) { | 11740 if (!node->IsPrimaryNode()) { |
12013 return node; | 11741 return node; |
12014 } | 11742 } |
12015 PrimaryNode* primary = node->AsPrimaryNode(); | 11743 PrimaryNode* primary = node->AsPrimaryNode(); |
12016 if (primary->primary().IsString()) { | 11744 if (primary->primary().IsString()) { |
12017 if (primary->IsSuper()) { | 11745 if (primary->IsSuper()) { |
12018 return primary; | 11746 return primary; |
12019 } | 11747 } |
12020 // In a static method, evaluation of an unresolved identifier causes a | 11748 // In a static method, evaluation of an unresolved identifier causes a |
(...skipping 18 matching lines...) Expand all Loading... |
12039 getter->set_is_deferred(primary->is_deferred_reference()); | 11767 getter->set_is_deferred(primary->is_deferred_reference()); |
12040 return getter; | 11768 return getter; |
12041 } else { | 11769 } else { |
12042 AstNode* receiver = LoadReceiver(primary->token_pos()); | 11770 AstNode* receiver = LoadReceiver(primary->token_pos()); |
12043 return CallGetter(node->token_pos(), receiver, name); | 11771 return CallGetter(node->token_pos(), receiver, name); |
12044 } | 11772 } |
12045 } | 11773 } |
12046 return primary; | 11774 return primary; |
12047 } | 11775 } |
12048 | 11776 |
12049 | |
12050 AstNode* Parser::LoadClosure(PrimaryNode* primary) { | 11777 AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
12051 ASSERT(primary->primary().IsFunction()); | 11778 ASSERT(primary->primary().IsFunction()); |
12052 const Function& func = | 11779 const Function& func = |
12053 Function::Cast(Object::ZoneHandle(primary->primary().raw())); | 11780 Function::Cast(Object::ZoneHandle(primary->primary().raw())); |
12054 const String& funcname = String::ZoneHandle(Z, func.name()); | 11781 const String& funcname = String::ZoneHandle(Z, func.name()); |
12055 if (func.is_static()) { | 11782 if (func.is_static()) { |
12056 // Static function access. | 11783 // Static function access. |
12057 ClosureNode* closure = | 11784 ClosureNode* closure = |
12058 CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 11785 CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
12059 closure->set_is_deferred(primary->is_deferred_reference()); | 11786 closure->set_is_deferred(primary->is_deferred_reference()); |
12060 return closure; | 11787 return closure; |
12061 } else { | 11788 } else { |
12062 // Instance function access. | 11789 // Instance function access. |
12063 if (current_function().is_static() || | 11790 if (current_function().is_static() || |
12064 current_function().IsInFactoryScope()) { | 11791 current_function().IsInFactoryScope()) { |
12065 ReportError(primary->token_pos(), | 11792 ReportError(primary->token_pos(), |
12066 "cannot access instance method '%s' from static method", | 11793 "cannot access instance method '%s' from static method", |
12067 funcname.ToCString()); | 11794 funcname.ToCString()); |
12068 } | 11795 } |
12069 AstNode* receiver = LoadReceiver(primary->token_pos()); | 11796 AstNode* receiver = LoadReceiver(primary->token_pos()); |
12070 return CallGetter(primary->token_pos(), receiver, funcname); | 11797 return CallGetter(primary->token_pos(), receiver, funcname); |
12071 } | 11798 } |
12072 UNREACHABLE(); | 11799 UNREACHABLE(); |
12073 return NULL; | 11800 return NULL; |
12074 } | 11801 } |
12075 | 11802 |
12076 | |
12077 AstNode* Parser::LoadTypeParameter(PrimaryNode* primary) { | 11803 AstNode* Parser::LoadTypeParameter(PrimaryNode* primary) { |
12078 const TokenPosition primary_pos = primary->token_pos(); | 11804 const TokenPosition primary_pos = primary->token_pos(); |
12079 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | 11805 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
12080 type_parameter = TypeParameter::Cast(primary->primary()).raw(); | 11806 type_parameter = TypeParameter::Cast(primary->primary()).raw(); |
12081 if (type_parameter.IsClassTypeParameter()) { | 11807 if (type_parameter.IsClassTypeParameter()) { |
12082 if (ParsingStaticMember()) { | 11808 if (ParsingStaticMember()) { |
12083 const String& name = String::Handle(Z, type_parameter.name()); | 11809 const String& name = String::Handle(Z, type_parameter.name()); |
12084 ReportError(primary_pos, | 11810 ReportError(primary_pos, |
12085 "cannot access type parameter '%s' " | 11811 "cannot access type parameter '%s' " |
12086 "from static function", | 11812 "from static function", |
(...skipping 13 matching lines...) Expand all Loading... |
12100 if (FunctionLevel() > 0) { | 11826 if (FunctionLevel() > 0) { |
12101 // Make sure that the parent function type arguments are captured. | 11827 // Make sure that the parent function type arguments are captured. |
12102 CaptureFunctionTypeArguments(); | 11828 CaptureFunctionTypeArguments(); |
12103 } | 11829 } |
12104 } | 11830 } |
12105 ASSERT(type_parameter.IsFinalized()); | 11831 ASSERT(type_parameter.IsFinalized()); |
12106 ASSERT(!type_parameter.IsMalformed()); | 11832 ASSERT(!type_parameter.IsMalformed()); |
12107 return new (Z) TypeNode(primary_pos, type_parameter); | 11833 return new (Z) TypeNode(primary_pos, type_parameter); |
12108 } | 11834 } |
12109 | 11835 |
12110 | |
12111 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 11836 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
12112 AstNode* left = primary; | 11837 AstNode* left = primary; |
12113 while (true) { | 11838 while (true) { |
12114 AstNode* selector = NULL; | 11839 AstNode* selector = NULL; |
12115 if ((CurrentToken() == Token::kPERIOD) || | 11840 if ((CurrentToken() == Token::kPERIOD) || |
12116 (CurrentToken() == Token::kQM_PERIOD)) { | 11841 (CurrentToken() == Token::kQM_PERIOD)) { |
12117 // Unconditional or conditional property extraction or method call. | 11842 // Unconditional or conditional property extraction or method call. |
12118 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; | 11843 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; |
12119 ConsumeToken(); | 11844 ConsumeToken(); |
12120 if (left->IsPrimaryNode()) { | 11845 if (left->IsPrimaryNode()) { |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12348 } | 12073 } |
12349 } | 12074 } |
12350 // Done parsing selectors. | 12075 // Done parsing selectors. |
12351 return left; | 12076 return left; |
12352 } | 12077 } |
12353 ASSERT(selector != NULL); | 12078 ASSERT(selector != NULL); |
12354 left = selector; | 12079 left = selector; |
12355 } | 12080 } |
12356 } | 12081 } |
12357 | 12082 |
12358 | |
12359 // Closurization e#m of getter, setter, method or operator. | 12083 // Closurization e#m of getter, setter, method or operator. |
12360 AstNode* Parser::ParseClosurization(AstNode* primary) { | 12084 AstNode* Parser::ParseClosurization(AstNode* primary) { |
12361 if (!FLAG_support_deprecated_tearoff_syntax) { | 12085 if (!FLAG_support_deprecated_tearoff_syntax) { |
12362 ReportError("tear-off using the x#id syntax is a deprecated feature"); | 12086 ReportError("tear-off using the x#id syntax is a deprecated feature"); |
12363 return NULL; | 12087 return NULL; |
12364 } | 12088 } |
12365 ExpectToken(Token::kHASH); | 12089 ExpectToken(Token::kHASH); |
12366 TokenPosition property_pos = TokenPos(); | 12090 TokenPosition property_pos = TokenPos(); |
12367 bool is_setter_name = false; | 12091 bool is_setter_name = false; |
12368 | 12092 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12504 GrowableHandlePtrArray<const String> pieces(Z, 3); | 12228 GrowableHandlePtrArray<const String> pieces(Z, 3); |
12505 pieces.Add(Symbols::HashMark()); | 12229 pieces.Add(Symbols::HashMark()); |
12506 if (is_setter_name) { | 12230 if (is_setter_name) { |
12507 pieces.Add(Symbols::SetterPrefix()); | 12231 pieces.Add(Symbols::SetterPrefix()); |
12508 } | 12232 } |
12509 pieces.Add(extractor_name); | 12233 pieces.Add(extractor_name); |
12510 extractor_name = Symbols::FromConcatAll(T, pieces); | 12234 extractor_name = Symbols::FromConcatAll(T, pieces); |
12511 return new (Z) InstanceGetterNode(property_pos, primary, extractor_name); | 12235 return new (Z) InstanceGetterNode(property_pos, primary, extractor_name); |
12512 } | 12236 } |
12513 | 12237 |
12514 | |
12515 AstNode* Parser::ParsePostfixExpr() { | 12238 AstNode* Parser::ParsePostfixExpr() { |
12516 TRACE_PARSER("ParsePostfixExpr"); | 12239 TRACE_PARSER("ParsePostfixExpr"); |
12517 String* expr_ident = | 12240 String* expr_ident = |
12518 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 12241 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
12519 const TokenPosition expr_pos = TokenPos(); | 12242 const TokenPosition expr_pos = TokenPos(); |
12520 AstNode* expr = ParsePrimary(); | 12243 AstNode* expr = ParsePrimary(); |
12521 if (CurrentToken() == Token::kHASH) { | 12244 if (CurrentToken() == Token::kHASH) { |
12522 expr = LoadFieldIfUnresolved(expr); | 12245 expr = LoadFieldIfUnresolved(expr); |
12523 expr = ParseClosurization(expr); | 12246 expr = ParseClosurization(expr); |
12524 } else { | 12247 } else { |
(...skipping 20 matching lines...) Expand all Loading... |
12545 ASSERT(store != NULL); | 12268 ASSERT(store != NULL); |
12546 // The result is a pair of the (side effects of the) store followed by | 12269 // The result is a pair of the (side effects of the) store followed by |
12547 // the (value of the) initial value temp variable load. | 12270 // the (value of the) initial value temp variable load. |
12548 let_expr->AddNode(store); | 12271 let_expr->AddNode(store); |
12549 let_expr->AddNode(new (Z) LoadLocalNode(op_pos, temp)); | 12272 let_expr->AddNode(new (Z) LoadLocalNode(op_pos, temp)); |
12550 return let_expr; | 12273 return let_expr; |
12551 } | 12274 } |
12552 return expr; | 12275 return expr; |
12553 } | 12276 } |
12554 | 12277 |
12555 | |
12556 // Resolve the type parameters that may appear in the given signature from the | 12278 // Resolve the type parameters that may appear in the given signature from the |
12557 // signature function and current class. | 12279 // signature function and current class. |
12558 // Unresolved type classes get resolved later by the class finalizer. | 12280 // Unresolved type classes get resolved later by the class finalizer. |
12559 void Parser::ResolveSignature(const Function& signature) { | 12281 void Parser::ResolveSignature(const Function& signature) { |
12560 const Function& saved_innermost_function = | 12282 const Function& saved_innermost_function = |
12561 Function::Handle(Z, innermost_function().raw()); | 12283 Function::Handle(Z, innermost_function().raw()); |
12562 innermost_function_ = signature.raw(); | 12284 innermost_function_ = signature.raw(); |
12563 AbstractType& type = AbstractType::Handle(); | 12285 AbstractType& type = AbstractType::Handle(); |
12564 // Resolve upper bounds of function type parameters. | 12286 // Resolve upper bounds of function type parameters. |
12565 const intptr_t num_type_params = signature.NumTypeParameters(); | 12287 const intptr_t num_type_params = signature.NumTypeParameters(); |
(...skipping 15 matching lines...) Expand all Loading... |
12581 // Resolve formal parameter types. | 12303 // Resolve formal parameter types. |
12582 const intptr_t num_parameters = signature.NumParameters(); | 12304 const intptr_t num_parameters = signature.NumParameters(); |
12583 for (intptr_t i = 0; i < num_parameters; i++) { | 12305 for (intptr_t i = 0; i < num_parameters; i++) { |
12584 type = signature.ParameterTypeAt(i); | 12306 type = signature.ParameterTypeAt(i); |
12585 ResolveType(&type); | 12307 ResolveType(&type); |
12586 signature.SetParameterTypeAt(i, type); | 12308 signature.SetParameterTypeAt(i, type); |
12587 } | 12309 } |
12588 innermost_function_ = saved_innermost_function.raw(); | 12310 innermost_function_ = saved_innermost_function.raw(); |
12589 } | 12311 } |
12590 | 12312 |
12591 | |
12592 // Resolve the type parameters that may appear in the given type and in its type | 12313 // Resolve the type parameters that may appear in the given type and in its type |
12593 // arguments from the current function and current class. | 12314 // arguments from the current function and current class. |
12594 // Unresolved type classes get resolved later by the class finalizer. | 12315 // Unresolved type classes get resolved later by the class finalizer. |
12595 void Parser::ResolveType(AbstractType* type) { | 12316 void Parser::ResolveType(AbstractType* type) { |
12596 ASSERT(type != NULL); | 12317 ASSERT(type != NULL); |
12597 if (type->IsResolved()) { | 12318 if (type->IsResolved()) { |
12598 // Some types are resolved by definition, such as a TypeParameter. | 12319 // Some types are resolved by definition, such as a TypeParameter. |
12599 return; | 12320 return; |
12600 } | 12321 } |
12601 // Resolve type class. | 12322 // Resolve type class. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12681 Function::Handle(Z, Type::Cast(*type).signature()); | 12402 Function::Handle(Z, Type::Cast(*type).signature()); |
12682 Type& signature_type = Type::Handle(Z, signature.SignatureType()); | 12403 Type& signature_type = Type::Handle(Z, signature.SignatureType()); |
12683 if (signature_type.raw() != type->raw()) { | 12404 if (signature_type.raw() != type->raw()) { |
12684 ResolveType(&signature_type); | 12405 ResolveType(&signature_type); |
12685 } else { | 12406 } else { |
12686 ResolveSignature(signature); | 12407 ResolveSignature(signature); |
12687 } | 12408 } |
12688 } | 12409 } |
12689 } | 12410 } |
12690 | 12411 |
12691 | |
12692 RawAbstractType* Parser::CanonicalizeType(const AbstractType& type) { | 12412 RawAbstractType* Parser::CanonicalizeType(const AbstractType& type) { |
12693 // If the current class is the result of a mixin application, we must | 12413 // If the current class is the result of a mixin application, we must |
12694 // use the class scope of the class from which the function originates. | 12414 // use the class scope of the class from which the function originates. |
12695 if (current_class().IsMixinApplication()) { | 12415 if (current_class().IsMixinApplication()) { |
12696 return ClassFinalizer::FinalizeType( | 12416 return ClassFinalizer::FinalizeType( |
12697 Class::Handle(Z, parsed_function()->function().origin()), type); | 12417 Class::Handle(Z, parsed_function()->function().origin()), type); |
12698 } | 12418 } |
12699 return ClassFinalizer::FinalizeType(current_class(), type); | 12419 return ClassFinalizer::FinalizeType(current_class(), type); |
12700 } | 12420 } |
12701 | 12421 |
12702 | |
12703 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 12422 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
12704 if (current_block_ == NULL) { | 12423 if (current_block_ == NULL) { |
12705 return NULL; | 12424 return NULL; |
12706 } | 12425 } |
12707 // A found name is treated as accessed and possibly marked as captured. | 12426 // A found name is treated as accessed and possibly marked as captured. |
12708 const bool kTestOnly = false; | 12427 const bool kTestOnly = false; |
12709 return current_block_->scope->LookupVariable(ident, kTestOnly); | 12428 return current_block_->scope->LookupVariable(ident, kTestOnly); |
12710 } | 12429 } |
12711 | 12430 |
12712 | |
12713 void Parser::CheckInstanceFieldAccess(TokenPosition field_pos, | 12431 void Parser::CheckInstanceFieldAccess(TokenPosition field_pos, |
12714 const String& field_name) { | 12432 const String& field_name) { |
12715 // Fields are not accessible from a static function, except from a | 12433 // Fields are not accessible from a static function, except from a |
12716 // constructor, which is considered as non-static by the compiler. | 12434 // constructor, which is considered as non-static by the compiler. |
12717 if (current_function().is_static()) { | 12435 if (current_function().is_static()) { |
12718 ReportError(field_pos, | 12436 ReportError(field_pos, |
12719 "cannot access instance field '%s' from a static function", | 12437 "cannot access instance field '%s' from a static function", |
12720 field_name.ToCString()); | 12438 field_name.ToCString()); |
12721 } | 12439 } |
12722 } | 12440 } |
12723 | 12441 |
12724 | |
12725 bool Parser::ParsingStaticMember() const { | 12442 bool Parser::ParsingStaticMember() const { |
12726 if (is_top_level_) { | 12443 if (is_top_level_) { |
12727 return (current_member_ != NULL) && current_member_->has_static && | 12444 return (current_member_ != NULL) && current_member_->has_static && |
12728 !current_member_->has_factory; | 12445 !current_member_->has_factory; |
12729 } | 12446 } |
12730 ASSERT(!current_function().IsNull()); | 12447 ASSERT(!current_function().IsNull()); |
12731 return current_function().is_static() && | 12448 return current_function().is_static() && |
12732 !current_function().IsInFactoryScope(); | 12449 !current_function().IsInFactoryScope(); |
12733 } | 12450 } |
12734 | 12451 |
12735 | |
12736 const AbstractType* Parser::ReceiverType(const Class& cls) { | 12452 const AbstractType* Parser::ReceiverType(const Class& cls) { |
12737 ASSERT(!cls.IsNull()); | 12453 ASSERT(!cls.IsNull()); |
12738 ASSERT(!cls.IsTypedefClass()); | 12454 ASSERT(!cls.IsTypedefClass()); |
12739 // Note that if cls is _Closure, the returned type will be _Closure, | 12455 // Note that if cls is _Closure, the returned type will be _Closure, |
12740 // and not the signature type. | 12456 // and not the signature type. |
12741 Type& type = Type::ZoneHandle(Z, cls.CanonicalType()); | 12457 Type& type = Type::ZoneHandle(Z, cls.CanonicalType()); |
12742 if (!type.IsNull()) { | 12458 if (!type.IsNull()) { |
12743 return &type; | 12459 return &type; |
12744 } | 12460 } |
12745 type = Type::New(cls, TypeArguments::Handle(Z, cls.type_parameters()), | 12461 type = Type::New(cls, TypeArguments::Handle(Z, cls.type_parameters()), |
12746 cls.token_pos(), Heap::kOld); | 12462 cls.token_pos(), Heap::kOld); |
12747 if (cls.is_type_finalized()) { | 12463 if (cls.is_type_finalized()) { |
12748 type ^= ClassFinalizer::FinalizeType(cls, type); | 12464 type ^= ClassFinalizer::FinalizeType(cls, type); |
12749 // Note that the receiver type may now be a malbounded type. | 12465 // Note that the receiver type may now be a malbounded type. |
12750 cls.SetCanonicalType(type); | 12466 cls.SetCanonicalType(type); |
12751 } | 12467 } |
12752 return &type; | 12468 return &type; |
12753 } | 12469 } |
12754 | 12470 |
12755 | |
12756 bool Parser::IsInstantiatorRequired() const { | 12471 bool Parser::IsInstantiatorRequired() const { |
12757 ASSERT(!current_function().IsNull()); | 12472 ASSERT(!current_function().IsNull()); |
12758 if (current_function().is_static() && | 12473 if (current_function().is_static() && |
12759 !current_function().IsInFactoryScope()) { | 12474 !current_function().IsInFactoryScope()) { |
12760 return false; | 12475 return false; |
12761 } | 12476 } |
12762 return current_class().IsGeneric(); | 12477 return current_class().IsGeneric(); |
12763 } | 12478 } |
12764 | 12479 |
12765 | |
12766 bool Parser::InGenericFunctionScope() const { | 12480 bool Parser::InGenericFunctionScope() const { |
12767 if (!innermost_function().IsNull()) { | 12481 if (!innermost_function().IsNull()) { |
12768 // With one more free tag bit in Function, we could cache this information. | 12482 // With one more free tag bit in Function, we could cache this information. |
12769 if (innermost_function().IsGeneric() || | 12483 if (innermost_function().IsGeneric() || |
12770 innermost_function().HasGenericParent()) { | 12484 innermost_function().HasGenericParent()) { |
12771 return true; | 12485 return true; |
12772 } | 12486 } |
12773 } | 12487 } |
12774 return false; | 12488 return false; |
12775 } | 12489 } |
12776 | 12490 |
12777 | |
12778 void Parser::InsertCachedConstantValue(const Script& script, | 12491 void Parser::InsertCachedConstantValue(const Script& script, |
12779 TokenPosition token_pos, | 12492 TokenPosition token_pos, |
12780 const Instance& value) { | 12493 const Instance& value) { |
12781 ASSERT(Thread::Current()->IsMutatorThread()); | 12494 ASSERT(Thread::Current()->IsMutatorThread()); |
12782 const intptr_t kInitialConstMapSize = 16; | 12495 const intptr_t kInitialConstMapSize = 16; |
12783 ASSERT(!script.InVMHeap()); | 12496 ASSERT(!script.InVMHeap()); |
12784 if (script.compile_time_constants() == Array::null()) { | 12497 if (script.compile_time_constants() == Array::null()) { |
12785 const Array& array = Array::Handle( | 12498 const Array& array = Array::Handle( |
12786 HashTables::New<ConstantsMap>(kInitialConstMapSize, Heap::kOld)); | 12499 HashTables::New<ConstantsMap>(kInitialConstMapSize, Heap::kOld)); |
12787 script.set_compile_time_constants(array); | 12500 script.set_compile_time_constants(array); |
12788 } | 12501 } |
12789 ConstantsMap constants(script.compile_time_constants()); | 12502 ConstantsMap constants(script.compile_time_constants()); |
12790 constants.InsertNewOrGetValue(token_pos, value); | 12503 constants.InsertNewOrGetValue(token_pos, value); |
12791 script.set_compile_time_constants(constants.Release()); | 12504 script.set_compile_time_constants(constants.Release()); |
12792 } | 12505 } |
12793 | 12506 |
12794 | |
12795 void Parser::CacheConstantValue(TokenPosition token_pos, | 12507 void Parser::CacheConstantValue(TokenPosition token_pos, |
12796 const Instance& value) { | 12508 const Instance& value) { |
12797 if (current_function().kind() == RawFunction::kImplicitStaticFinalGetter) { | 12509 if (current_function().kind() == RawFunction::kImplicitStaticFinalGetter) { |
12798 // Don't cache constants in initializer expressions. They get | 12510 // Don't cache constants in initializer expressions. They get |
12799 // evaluated only once. | 12511 // evaluated only once. |
12800 return; | 12512 return; |
12801 } | 12513 } |
12802 InsertCachedConstantValue(script_, token_pos, value); | 12514 InsertCachedConstantValue(script_, token_pos, value); |
12803 INC_STAT(thread_, num_cached_consts, 1); | 12515 INC_STAT(thread_, num_cached_consts, 1); |
12804 } | 12516 } |
12805 | 12517 |
12806 | |
12807 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) { | 12518 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) { |
12808 bool is_present = false; | 12519 bool is_present = false; |
12809 ASSERT(!script_.InVMHeap()); | 12520 ASSERT(!script_.InVMHeap()); |
12810 if (script_.compile_time_constants() == Array::null()) { | 12521 if (script_.compile_time_constants() == Array::null()) { |
12811 return false; | 12522 return false; |
12812 } | 12523 } |
12813 ConstantsMap constants(script_.compile_time_constants()); | 12524 ConstantsMap constants(script_.compile_time_constants()); |
12814 *value ^= constants.GetOrNull(token_pos, &is_present); | 12525 *value ^= constants.GetOrNull(token_pos, &is_present); |
12815 // Mutator compiler thread may add constants while background compiler | 12526 // Mutator compiler thread may add constants while background compiler |
12816 // is running, and thus change the value of 'compile_time_constants'; | 12527 // is running, and thus change the value of 'compile_time_constants'; |
12817 // do not assert that 'compile_time_constants' has not changed. | 12528 // do not assert that 'compile_time_constants' has not changed. |
12818 constants.Release(); | 12529 constants.Release(); |
12819 if (FLAG_compiler_stats && is_present) { | 12530 if (FLAG_compiler_stats && is_present) { |
12820 thread_->compiler_stats()->num_const_cache_hits++; | 12531 thread_->compiler_stats()->num_const_cache_hits++; |
12821 } | 12532 } |
12822 return is_present; | 12533 return is_present; |
12823 } | 12534 } |
12824 | 12535 |
12825 | |
12826 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 12536 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
12827 TokenPosition token_pos) { | 12537 TokenPosition token_pos) { |
12828 if (instance.IsNull()) { | 12538 if (instance.IsNull()) { |
12829 return instance.raw(); | 12539 return instance.raw(); |
12830 } | 12540 } |
12831 const char* error_str = NULL; | 12541 const char* error_str = NULL; |
12832 Instance& result = | 12542 Instance& result = |
12833 Instance::Handle(Z, instance.CheckAndCanonicalize(thread(), &error_str)); | 12543 Instance::Handle(Z, instance.CheckAndCanonicalize(thread(), &error_str)); |
12834 if (result.IsNull()) { | 12544 if (result.IsNull()) { |
12835 ReportError(token_pos, "Invalid const object %s", error_str); | 12545 ReportError(token_pos, "Invalid const object %s", error_str); |
12836 } | 12546 } |
12837 return result.raw(); | 12547 return result.raw(); |
12838 } | 12548 } |
12839 | 12549 |
12840 | |
12841 // If the field is already initialized, return no ast (NULL). | 12550 // If the field is already initialized, return no ast (NULL). |
12842 // Otherwise, if the field is constant, initialize the field and return no ast. | 12551 // Otherwise, if the field is constant, initialize the field and return no ast. |
12843 // If the field is not initialized and not const, return the ast for the getter. | 12552 // If the field is not initialized and not const, return the ast for the getter. |
12844 StaticGetterNode* Parser::RunStaticFieldInitializer( | 12553 StaticGetterNode* Parser::RunStaticFieldInitializer( |
12845 const Field& field, | 12554 const Field& field, |
12846 TokenPosition field_ref_pos) { | 12555 TokenPosition field_ref_pos) { |
12847 ASSERT(field.is_static()); | 12556 ASSERT(field.is_static()); |
12848 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); | 12557 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); |
12849 const String& field_name = String::ZoneHandle(Z, field.name()); | 12558 const String& field_name = String::ZoneHandle(Z, field.name()); |
12850 const String& getter_name = | 12559 const String& getter_name = |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12909 } | 12618 } |
12910 } | 12619 } |
12911 if (getter.IsNull() || | 12620 if (getter.IsNull() || |
12912 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { | 12621 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
12913 return NULL; | 12622 return NULL; |
12914 } | 12623 } |
12915 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 12624 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
12916 return new (Z) StaticGetterNode(field_ref_pos, NULL, field_owner, field_name); | 12625 return new (Z) StaticGetterNode(field_ref_pos, NULL, field_owner, field_name); |
12917 } | 12626 } |
12918 | 12627 |
12919 | |
12920 RawObject* Parser::EvaluateConstConstructorCall( | 12628 RawObject* Parser::EvaluateConstConstructorCall( |
12921 const Class& type_class, | 12629 const Class& type_class, |
12922 const TypeArguments& type_arguments, | 12630 const TypeArguments& type_arguments, |
12923 const Function& constructor, | 12631 const Function& constructor, |
12924 ArgumentListNode* arguments) { | 12632 ArgumentListNode* arguments) { |
12925 NoReloadScope no_reload_scope(isolate(), thread()); | 12633 NoReloadScope no_reload_scope(isolate(), thread()); |
12926 NoOOBMessageScope no_msg_scope(thread()); | 12634 NoOOBMessageScope no_msg_scope(thread()); |
12927 // Factories and constructors are not generic functions. | 12635 // Factories and constructors are not generic functions. |
12928 const int kTypeArgsLen = 0; | 12636 const int kTypeArgsLen = 0; |
12929 // Factories have one extra argument: the type arguments. | 12637 // Factories have one extra argument: the type arguments. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12973 } | 12681 } |
12974 } else { | 12682 } else { |
12975 if (constructor.IsFactory()) { | 12683 if (constructor.IsFactory()) { |
12976 // The factory method returns the allocated object. | 12684 // The factory method returns the allocated object. |
12977 instance ^= result.raw(); | 12685 instance ^= result.raw(); |
12978 } | 12686 } |
12979 return TryCanonicalize(instance, TokenPos()); | 12687 return TryCanonicalize(instance, TokenPos()); |
12980 } | 12688 } |
12981 } | 12689 } |
12982 | 12690 |
12983 | |
12984 // Do a lookup for the identifier in the block scope and the class scope | 12691 // Do a lookup for the identifier in the block scope and the class scope |
12985 // return true if the identifier is found, false otherwise. | 12692 // return true if the identifier is found, false otherwise. |
12986 // If node is non NULL return an AST node corresponding to the identifier. | 12693 // If node is non NULL return an AST node corresponding to the identifier. |
12987 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, | 12694 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, |
12988 const String& ident, | 12695 const String& ident, |
12989 AstNode** node, | 12696 AstNode** node, |
12990 intptr_t* function_level) { | 12697 intptr_t* function_level) { |
12991 TRACE_PARSER("ResolveIdentInLocalScope"); | 12698 TRACE_PARSER("ResolveIdentInLocalScope"); |
12992 // First try to find the identifier in the nested local scopes. | 12699 // First try to find the identifier in the nested local scopes. |
12993 LocalVariable* local = LookupLocalScope(ident); | 12700 LocalVariable* local = LookupLocalScope(ident); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13081 } | 12788 } |
13082 } | 12789 } |
13083 | 12790 |
13084 // Nothing found in scope of current class. | 12791 // Nothing found in scope of current class. |
13085 if (node != NULL) { | 12792 if (node != NULL) { |
13086 *node = NULL; | 12793 *node = NULL; |
13087 } | 12794 } |
13088 return false; | 12795 return false; |
13089 } | 12796 } |
13090 | 12797 |
13091 | |
13092 // Resolve an identifier by checking the global scope of the current | 12798 // Resolve an identifier by checking the global scope of the current |
13093 // library. If not found in the current library, then look in the scopes | 12799 // library. If not found in the current library, then look in the scopes |
13094 // of all libraries that are imported without a library prefix. | 12800 // of all libraries that are imported without a library prefix. |
13095 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos, | 12801 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos, |
13096 const String& ident) { | 12802 const String& ident) { |
13097 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 12803 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
13098 HANDLESCOPE(thread()); | 12804 HANDLESCOPE(thread()); |
13099 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); | 12805 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); |
13100 if (obj.IsClass()) { | 12806 if (obj.IsClass()) { |
13101 const Class& cls = Class::Cast(obj); | 12807 const Class& cls = Class::Cast(obj); |
(...skipping 23 matching lines...) Expand all Loading... |
13125 const LibraryPrefix& prefix = LibraryPrefix::Cast(obj); | 12831 const LibraryPrefix& prefix = LibraryPrefix::Cast(obj); |
13126 ReportError(ident_pos, "illegal use of library prefix '%s'", | 12832 ReportError(ident_pos, "illegal use of library prefix '%s'", |
13127 String::Handle(prefix.name()).ToCString()); | 12833 String::Handle(prefix.name()).ToCString()); |
13128 } else { | 12834 } else { |
13129 ASSERT(obj.IsNull()); | 12835 ASSERT(obj.IsNull()); |
13130 } | 12836 } |
13131 // Lexically unresolved primary identifiers are referenced by their name. | 12837 // Lexically unresolved primary identifiers are referenced by their name. |
13132 return new (Z) PrimaryNode(ident_pos, ident); | 12838 return new (Z) PrimaryNode(ident_pos, ident); |
13133 } | 12839 } |
13134 | 12840 |
13135 | |
13136 // Do a lookup for the identifier in the scope of the specified | 12841 // Do a lookup for the identifier in the scope of the specified |
13137 // library prefix. This means trying to resolve it locally in all of the | 12842 // library prefix. This means trying to resolve it locally in all of the |
13138 // libraries present in the library prefix. | 12843 // libraries present in the library prefix. |
13139 AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos, | 12844 AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos, |
13140 const LibraryPrefix& prefix, | 12845 const LibraryPrefix& prefix, |
13141 const String& ident) { | 12846 const String& ident) { |
13142 TRACE_PARSER("ResolveIdentInPrefixScope"); | 12847 TRACE_PARSER("ResolveIdentInPrefixScope"); |
13143 HANDLESCOPE(thread()); | 12848 HANDLESCOPE(thread()); |
13144 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 12849 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
13145 // Private names are not exported by libraries. The name mangling | 12850 // Private names are not exported by libraries. The name mangling |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13204 primary->set_prefix(&prefix); | 12909 primary->set_prefix(&prefix); |
13205 } | 12910 } |
13206 return primary; | 12911 return primary; |
13207 } | 12912 } |
13208 } | 12913 } |
13209 // All possible object types are handled above. | 12914 // All possible object types are handled above. |
13210 UNREACHABLE(); | 12915 UNREACHABLE(); |
13211 return NULL; | 12916 return NULL; |
13212 } | 12917 } |
13213 | 12918 |
13214 | |
13215 // Resolve identifier. Issue an error message if | 12919 // Resolve identifier. Issue an error message if |
13216 // the ident refers to a method and allow_closure_names is false. | 12920 // the ident refers to a method and allow_closure_names is false. |
13217 // If the name cannot be resolved, turn it into an instance field access | 12921 // If the name cannot be resolved, turn it into an instance field access |
13218 // if we're compiling an instance method, or generate | 12922 // if we're compiling an instance method, or generate |
13219 // throw NoSuchMethodError if we're compiling a static method. | 12923 // throw NoSuchMethodError if we're compiling a static method. |
13220 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, | 12924 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, |
13221 const String& ident, | 12925 const String& ident, |
13222 bool allow_closure_names) { | 12926 bool allow_closure_names) { |
13223 TRACE_PARSER("ResolveIdent"); | 12927 TRACE_PARSER("ResolveIdent"); |
13224 // First try to find the variable in the local scope (block scope or | 12928 // First try to find the variable in the local scope (block scope or |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13295 type ^= CanonicalizeType(type); | 12999 type ^= CanonicalizeType(type); |
13296 // Type may be malbounded, but not malformed. | 13000 // Type may be malbounded, but not malformed. |
13297 ASSERT(!type.IsMalformed()); | 13001 ASSERT(!type.IsMalformed()); |
13298 resolved = | 13002 resolved = |
13299 new (Z) TypeNode(primary_pos, type, primary->is_deferred_reference()); | 13003 new (Z) TypeNode(primary_pos, type, primary->is_deferred_reference()); |
13300 } | 13004 } |
13301 } | 13005 } |
13302 return resolved; | 13006 return resolved; |
13303 } | 13007 } |
13304 | 13008 |
13305 | |
13306 RawAbstractType* Parser::ParseType( | 13009 RawAbstractType* Parser::ParseType( |
13307 ClassFinalizer::FinalizationKind finalization, | 13010 ClassFinalizer::FinalizationKind finalization, |
13308 bool allow_deferred_type, | 13011 bool allow_deferred_type, |
13309 bool consume_unresolved_prefix) { | 13012 bool consume_unresolved_prefix) { |
13310 LibraryPrefix& prefix = LibraryPrefix::Handle(Z); | 13013 LibraryPrefix& prefix = LibraryPrefix::Handle(Z); |
13311 return ParseType(finalization, allow_deferred_type, consume_unresolved_prefix, | 13014 return ParseType(finalization, allow_deferred_type, consume_unresolved_prefix, |
13312 &prefix); | 13015 &prefix); |
13313 } | 13016 } |
13314 | 13017 |
13315 | |
13316 // Parses and returns a type or a function type. | 13018 // Parses and returns a type or a function type. |
13317 RawAbstractType* Parser::ParseTypeOrFunctionType( | 13019 RawAbstractType* Parser::ParseTypeOrFunctionType( |
13318 bool allow_void, | 13020 bool allow_void, |
13319 ClassFinalizer::FinalizationKind finalization) { | 13021 ClassFinalizer::FinalizationKind finalization) { |
13320 TRACE_PARSER("ParseTypeOrFunctionType"); | 13022 TRACE_PARSER("ParseTypeOrFunctionType"); |
13321 AbstractType& type = AbstractType::Handle(Z); | 13023 AbstractType& type = AbstractType::Handle(Z); |
13322 if (CurrentToken() == Token::kVOID) { | 13024 if (CurrentToken() == Token::kVOID) { |
13323 TokenPosition void_pos = TokenPos(); | 13025 TokenPosition void_pos = TokenPos(); |
13324 type = Type::VoidType(); | 13026 type = Type::VoidType(); |
13325 ConsumeToken(); | 13027 ConsumeToken(); |
(...skipping 20 matching lines...) Expand all Loading... |
13346 } | 13048 } |
13347 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 13049 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
13348 ResolveType(&type); | 13050 ResolveType(&type); |
13349 if (finalization >= ClassFinalizer::kCanonicalize) { | 13051 if (finalization >= ClassFinalizer::kCanonicalize) { |
13350 type ^= CanonicalizeType(type); | 13052 type ^= CanonicalizeType(type); |
13351 } | 13053 } |
13352 } | 13054 } |
13353 return type.raw(); | 13055 return type.raw(); |
13354 } | 13056 } |
13355 | 13057 |
13356 | |
13357 // Parses and returns a function type. | 13058 // Parses and returns a function type. |
13358 // If 'result_type' is not null, parsing of the result type is skipped. | 13059 // If 'result_type' is not null, parsing of the result type is skipped. |
13359 RawType* Parser::ParseFunctionType( | 13060 RawType* Parser::ParseFunctionType( |
13360 const AbstractType& result_type, | 13061 const AbstractType& result_type, |
13361 ClassFinalizer::FinalizationKind finalization) { | 13062 ClassFinalizer::FinalizationKind finalization) { |
13362 TRACE_PARSER("ParseFunctionType"); | 13063 TRACE_PARSER("ParseFunctionType"); |
13363 AbstractType& type = AbstractType::Handle(Z, result_type.raw()); | 13064 AbstractType& type = AbstractType::Handle(Z, result_type.raw()); |
13364 if (type.IsNull()) { | 13065 if (type.IsNull()) { |
13365 if (CurrentToken() == Token::kVOID) { | 13066 if (CurrentToken() == Token::kVOID) { |
13366 ConsumeToken(); | 13067 ConsumeToken(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13423 } | 13124 } |
13424 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 13125 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
13425 ResolveType(&type); | 13126 ResolveType(&type); |
13426 if (finalization >= ClassFinalizer::kCanonicalize) { | 13127 if (finalization >= ClassFinalizer::kCanonicalize) { |
13427 type ^= CanonicalizeType(type); | 13128 type ^= CanonicalizeType(type); |
13428 } | 13129 } |
13429 } | 13130 } |
13430 return Type::RawCast(type.raw()); | 13131 return Type::RawCast(type.raw()); |
13431 } | 13132 } |
13432 | 13133 |
13433 | |
13434 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 13134 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
13435 // finalize it according to the given type finalization mode. | 13135 // finalize it according to the given type finalization mode. |
13436 // Returns type and sets prefix. | 13136 // Returns type and sets prefix. |
13437 RawAbstractType* Parser::ParseType( | 13137 RawAbstractType* Parser::ParseType( |
13438 ClassFinalizer::FinalizationKind finalization, | 13138 ClassFinalizer::FinalizationKind finalization, |
13439 bool allow_deferred_type, | 13139 bool allow_deferred_type, |
13440 bool consume_unresolved_prefix, | 13140 bool consume_unresolved_prefix, |
13441 LibraryPrefix* prefix) { | 13141 LibraryPrefix* prefix) { |
13442 TRACE_PARSER("ParseType"); | 13142 TRACE_PARSER("ParseType"); |
13443 CheckToken(Token::kIDENT, "type name expected"); | 13143 CheckToken(Token::kIDENT, "type name expected"); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13510 } | 13210 } |
13511 // If the deferred prefixes are not allowed, or if the prefix is not yet | 13211 // If the deferred prefixes are not allowed, or if the prefix is not yet |
13512 // loaded when finalization is requested, return a malformed type. | 13212 // loaded when finalization is requested, return a malformed type. |
13513 // Otherwise, handle resolution below, as needed. | 13213 // Otherwise, handle resolution below, as needed. |
13514 if (!allow_deferred_type || | 13214 if (!allow_deferred_type || |
13515 (!prefix->is_loaded() && | 13215 (!prefix->is_loaded() && |
13516 (finalization > ClassFinalizer::kResolveTypeParameters))) { | 13216 (finalization > ClassFinalizer::kResolveTypeParameters))) { |
13517 ParseTypeArguments(ClassFinalizer::kIgnore); | 13217 ParseTypeArguments(ClassFinalizer::kIgnore); |
13518 return ClassFinalizer::NewFinalizedMalformedType( | 13218 return ClassFinalizer::NewFinalizedMalformedType( |
13519 Error::Handle(Z), // No previous error. | 13219 Error::Handle(Z), // No previous error. |
13520 script_, ident_pos, !prefix->is_loaded() && allow_deferred_type | 13220 script_, ident_pos, |
13521 ? "deferred type '%s.%s' is not yet loaded" | 13221 !prefix->is_loaded() && allow_deferred_type |
13522 : "using deferred type '%s.%s' is invalid", | 13222 ? "deferred type '%s.%s' is not yet loaded" |
| 13223 : "using deferred type '%s.%s' is invalid", |
13523 String::Handle(Z, prefix->name()).ToCString(), | 13224 String::Handle(Z, prefix->name()).ToCString(), |
13524 type_name.ToCString()); | 13225 type_name.ToCString()); |
13525 } | 13226 } |
13526 } | 13227 } |
13527 } | 13228 } |
13528 Object& type_class = Object::Handle(Z); | 13229 Object& type_class = Object::Handle(Z); |
13529 // Leave type_class as null if type finalization mode is kIgnore. | 13230 // Leave type_class as null if type finalization mode is kIgnore. |
13530 if (finalization != ClassFinalizer::kIgnore) { | 13231 if (finalization != ClassFinalizer::kIgnore) { |
13531 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); | 13232 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); |
13532 } | 13233 } |
13533 TypeArguments& type_arguments = | 13234 TypeArguments& type_arguments = |
13534 TypeArguments::Handle(Z, ParseTypeArguments(finalization)); | 13235 TypeArguments::Handle(Z, ParseTypeArguments(finalization)); |
13535 if (finalization == ClassFinalizer::kIgnore) { | 13236 if (finalization == ClassFinalizer::kIgnore) { |
13536 return Type::DynamicType(); | 13237 return Type::DynamicType(); |
13537 } | 13238 } |
13538 AbstractType& type = AbstractType::Handle( | 13239 AbstractType& type = AbstractType::Handle( |
13539 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); | 13240 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); |
13540 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 13241 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
13541 ResolveType(&type); | 13242 ResolveType(&type); |
13542 if (finalization >= ClassFinalizer::kCanonicalize) { | 13243 if (finalization >= ClassFinalizer::kCanonicalize) { |
13543 type ^= CanonicalizeType(type); | 13244 type ^= CanonicalizeType(type); |
13544 } | 13245 } |
13545 } | 13246 } |
13546 return type.raw(); | 13247 return type.raw(); |
13547 } | 13248 } |
13548 | 13249 |
13549 | |
13550 void Parser::CheckConstructorCallTypeArguments( | 13250 void Parser::CheckConstructorCallTypeArguments( |
13551 TokenPosition pos, | 13251 TokenPosition pos, |
13552 const Function& constructor, | 13252 const Function& constructor, |
13553 const TypeArguments& type_arguments) { | 13253 const TypeArguments& type_arguments) { |
13554 if (!type_arguments.IsNull()) { | 13254 if (!type_arguments.IsNull()) { |
13555 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); | 13255 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); |
13556 ASSERT(!constructor_class.IsNull()); | 13256 ASSERT(!constructor_class.IsNull()); |
13557 ASSERT(constructor_class.is_finalized()); | 13257 ASSERT(constructor_class.is_finalized()); |
13558 ASSERT(type_arguments.IsCanonical()); | 13258 ASSERT(type_arguments.IsCanonical()); |
13559 // Do not report the expected vs. actual number of type arguments, because | 13259 // Do not report the expected vs. actual number of type arguments, because |
13560 // the type argument vector is flattened and raw types are allowed. | 13260 // the type argument vector is flattened and raw types are allowed. |
13561 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 13261 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
13562 ReportError(pos, "wrong number of type arguments passed to constructor"); | 13262 ReportError(pos, "wrong number of type arguments passed to constructor"); |
13563 } | 13263 } |
13564 } | 13264 } |
13565 } | 13265 } |
13566 | 13266 |
13567 | |
13568 // Parse "[" [ expr { "," expr } ["," ] "]". | 13267 // Parse "[" [ expr { "," expr } ["," ] "]". |
13569 // Note: if the list literal is empty and the brackets have no whitespace | 13268 // Note: if the list literal is empty and the brackets have no whitespace |
13570 // between them, the scanner recognizes the opening and closing bracket | 13269 // between them, the scanner recognizes the opening and closing bracket |
13571 // as one token of type Token::kINDEX. | 13270 // as one token of type Token::kINDEX. |
13572 AstNode* Parser::ParseListLiteral(TokenPosition type_pos, | 13271 AstNode* Parser::ParseListLiteral(TokenPosition type_pos, |
13573 bool is_const, | 13272 bool is_const, |
13574 const TypeArguments& type_arguments) { | 13273 const TypeArguments& type_arguments) { |
13575 TRACE_PARSER("ParseListLiteral"); | 13274 TRACE_PARSER("ParseListLiteral"); |
13576 ASSERT(type_pos.IsReal()); | 13275 ASSERT(type_pos.IsReal()); |
13577 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 13276 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13720 factory_param->Add(empty_array_literal); | 13419 factory_param->Add(empty_array_literal); |
13721 } else { | 13420 } else { |
13722 ArrayNode* list = new (Z) ArrayNode(TokenPos(), type, element_list); | 13421 ArrayNode* list = new (Z) ArrayNode(TokenPos(), type, element_list); |
13723 factory_param->Add(list); | 13422 factory_param->Add(list); |
13724 } | 13423 } |
13725 return CreateConstructorCallNode(literal_pos, factory_type_args, | 13424 return CreateConstructorCallNode(literal_pos, factory_type_args, |
13726 factory_method, factory_param); | 13425 factory_method, factory_param); |
13727 } | 13426 } |
13728 } | 13427 } |
13729 | 13428 |
13730 | |
13731 ConstructorCallNode* Parser::CreateConstructorCallNode( | 13429 ConstructorCallNode* Parser::CreateConstructorCallNode( |
13732 TokenPosition token_pos, | 13430 TokenPosition token_pos, |
13733 const TypeArguments& type_arguments, | 13431 const TypeArguments& type_arguments, |
13734 const Function& constructor, | 13432 const Function& constructor, |
13735 ArgumentListNode* arguments) { | 13433 ArgumentListNode* arguments) { |
13736 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 13434 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
13737 EnsureExpressionTemp(); | 13435 EnsureExpressionTemp(); |
13738 } | 13436 } |
13739 return new (Z) | 13437 return new (Z) |
13740 ConstructorCallNode(token_pos, type_arguments, constructor, arguments); | 13438 ConstructorCallNode(token_pos, type_arguments, constructor, arguments); |
13741 } | 13439 } |
13742 | 13440 |
13743 | |
13744 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, | 13441 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, |
13745 bool is_const, | 13442 bool is_const, |
13746 AstNode* key, | 13443 AstNode* key, |
13747 AstNode* value) { | 13444 AstNode* value) { |
13748 if (is_const) { | 13445 if (is_const) { |
13749 ASSERT(key->IsLiteralNode()); | 13446 ASSERT(key->IsLiteralNode()); |
13750 const Instance& new_key = key->AsLiteralNode()->literal(); | 13447 const Instance& new_key = key->AsLiteralNode()->literal(); |
13751 for (int i = 0; i < pairs->length(); i += 2) { | 13448 for (int i = 0; i < pairs->length(); i += 2) { |
13752 const Instance& key_i = (*pairs)[i]->AsLiteralNode()->literal(); | 13449 const Instance& key_i = (*pairs)[i]->AsLiteralNode()->literal(); |
13753 // The keys of a compile time constant map are compile time | 13450 // The keys of a compile time constant map are compile time |
13754 // constants, i.e. canonicalized values. Thus, we can compare | 13451 // constants, i.e. canonicalized values. Thus, we can compare |
13755 // raw pointers to check for equality. | 13452 // raw pointers to check for equality. |
13756 if (new_key.raw() == key_i.raw()) { | 13453 if (new_key.raw() == key_i.raw()) { |
13757 // Duplicate key found. The new value replaces the previously | 13454 // Duplicate key found. The new value replaces the previously |
13758 // defined value. | 13455 // defined value. |
13759 (*pairs)[i + 1] = value; | 13456 (*pairs)[i + 1] = value; |
13760 return; | 13457 return; |
13761 } | 13458 } |
13762 } | 13459 } |
13763 } | 13460 } |
13764 pairs->Add(key); | 13461 pairs->Add(key); |
13765 pairs->Add(value); | 13462 pairs->Add(value); |
13766 } | 13463 } |
13767 | 13464 |
13768 | |
13769 AstNode* Parser::ParseMapLiteral(TokenPosition type_pos, | 13465 AstNode* Parser::ParseMapLiteral(TokenPosition type_pos, |
13770 bool is_const, | 13466 bool is_const, |
13771 const TypeArguments& type_arguments) { | 13467 const TypeArguments& type_arguments) { |
13772 TRACE_PARSER("ParseMapLiteral"); | 13468 TRACE_PARSER("ParseMapLiteral"); |
13773 ASSERT(type_pos.IsReal()); | 13469 ASSERT(type_pos.IsReal()); |
13774 ASSERT(CurrentToken() == Token::kLBRACE); | 13470 ASSERT(CurrentToken() == Token::kLBRACE); |
13775 const TokenPosition literal_pos = TokenPos(); | 13471 const TokenPosition literal_pos = TokenPos(); |
13776 | 13472 |
13777 if (is_const) { | 13473 if (is_const) { |
13778 Instance& existing_const = Instance::ZoneHandle(Z); | 13474 Instance& existing_const = Instance::ZoneHandle(Z); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13978 factory_param->Add(kv_pairs); | 13674 factory_param->Add(kv_pairs); |
13979 } | 13675 } |
13980 | 13676 |
13981 return CreateConstructorCallNode(literal_pos, factory_type_args, | 13677 return CreateConstructorCallNode(literal_pos, factory_type_args, |
13982 factory_method, factory_param); | 13678 factory_method, factory_param); |
13983 } | 13679 } |
13984 UNREACHABLE(); | 13680 UNREACHABLE(); |
13985 return NULL; | 13681 return NULL; |
13986 } | 13682 } |
13987 | 13683 |
13988 | |
13989 AstNode* Parser::ParseCompoundLiteral() { | 13684 AstNode* Parser::ParseCompoundLiteral() { |
13990 TRACE_PARSER("ParseCompoundLiteral"); | 13685 TRACE_PARSER("ParseCompoundLiteral"); |
13991 bool is_const = false; | 13686 bool is_const = false; |
13992 if (CurrentToken() == Token::kCONST) { | 13687 if (CurrentToken() == Token::kCONST) { |
13993 is_const = true; | 13688 is_const = true; |
13994 ConsumeToken(); | 13689 ConsumeToken(); |
13995 } | 13690 } |
13996 const TokenPosition type_pos = TokenPos(); | 13691 const TokenPosition type_pos = TokenPos(); |
13997 TypeArguments& type_arguments = TypeArguments::Handle( | 13692 TypeArguments& type_arguments = TypeArguments::Handle( |
13998 Z, ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 13693 Z, ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
13999 // Malformed type arguments are mapped to dynamic, so we will not encounter | 13694 // Malformed type arguments are mapped to dynamic, so we will not encounter |
14000 // them here. | 13695 // them here. |
14001 // Map and List interfaces do not declare bounds on their type parameters, so | 13696 // Map and List interfaces do not declare bounds on their type parameters, so |
14002 // we will not see malbounded type arguments here. | 13697 // we will not see malbounded type arguments here. |
14003 AstNode* primary = NULL; | 13698 AstNode* primary = NULL; |
14004 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { | 13699 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { |
14005 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 13700 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
14006 } else if (CurrentToken() == Token::kLBRACE) { | 13701 } else if (CurrentToken() == Token::kLBRACE) { |
14007 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 13702 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
14008 } else { | 13703 } else { |
14009 UnexpectedToken(); | 13704 UnexpectedToken(); |
14010 } | 13705 } |
14011 return primary; | 13706 return primary; |
14012 } | 13707 } |
14013 | 13708 |
14014 | |
14015 AstNode* Parser::ParseSymbolLiteral() { | 13709 AstNode* Parser::ParseSymbolLiteral() { |
14016 ASSERT(CurrentToken() == Token::kHASH); | 13710 ASSERT(CurrentToken() == Token::kHASH); |
14017 ConsumeToken(); | 13711 ConsumeToken(); |
14018 TokenPosition symbol_pos = TokenPos(); | 13712 TokenPosition symbol_pos = TokenPos(); |
14019 String& symbol = String::ZoneHandle(Z); | 13713 String& symbol = String::ZoneHandle(Z); |
14020 if (IsIdentifier()) { | 13714 if (IsIdentifier()) { |
14021 symbol = CurrentLiteral()->raw(); | 13715 symbol = CurrentLiteral()->raw(); |
14022 ConsumeToken(); | 13716 ConsumeToken(); |
14023 GrowableHandlePtrArray<const String> pieces(Z, 3); | 13717 GrowableHandlePtrArray<const String> pieces(Z, 3); |
14024 pieces.Add(symbol); | 13718 pieces.Add(symbol); |
(...skipping 29 matching lines...) Expand all Loading... |
14054 constr, constr_args)); | 13748 constr, constr_args)); |
14055 if (result.IsUnhandledException()) { | 13749 if (result.IsUnhandledException()) { |
14056 ReportErrors(Error::Cast(result), script_, symbol_pos, | 13750 ReportErrors(Error::Cast(result), script_, symbol_pos, |
14057 "error executing const Symbol constructor"); | 13751 "error executing const Symbol constructor"); |
14058 } | 13752 } |
14059 symbol_instance ^= result.raw(); | 13753 symbol_instance ^= result.raw(); |
14060 CacheConstantValue(symbol_pos, symbol_instance); | 13754 CacheConstantValue(symbol_pos, symbol_instance); |
14061 return new (Z) LiteralNode(symbol_pos, symbol_instance); | 13755 return new (Z) LiteralNode(symbol_pos, symbol_instance); |
14062 } | 13756 } |
14063 | 13757 |
14064 | |
14065 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, | 13758 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, |
14066 TokenPosition token_pos) { | 13759 TokenPosition token_pos) { |
14067 ASSERT(ctr.kind() == RawFunction::kConstructor); | 13760 ASSERT(ctr.kind() == RawFunction::kConstructor); |
14068 Function& closure = Function::Handle(Z); | 13761 Function& closure = Function::Handle(Z); |
14069 closure = I->LookupClosureFunction(innermost_function(), token_pos); | 13762 closure = I->LookupClosureFunction(innermost_function(), token_pos); |
14070 if (!closure.IsNull()) { | 13763 if (!closure.IsNull()) { |
14071 ASSERT(closure.IsConstructorClosureFunction()); | 13764 ASSERT(closure.IsConstructorClosureFunction()); |
14072 return closure.raw(); | 13765 return closure.raw(); |
14073 } | 13766 } |
14074 | 13767 |
(...skipping 22 matching lines...) Expand all Loading... |
14097 | 13790 |
14098 // Finalize function type. | 13791 // Finalize function type. |
14099 Type& signature_type = Type::Handle(Z, closure.SignatureType()); | 13792 Type& signature_type = Type::Handle(Z, closure.SignatureType()); |
14100 signature_type ^= CanonicalizeType(signature_type); | 13793 signature_type ^= CanonicalizeType(signature_type); |
14101 closure.SetSignatureType(signature_type); | 13794 closure.SetSignatureType(signature_type); |
14102 // Finalization would be premature when top-level parsing. | 13795 // Finalization would be premature when top-level parsing. |
14103 ASSERT(!is_top_level_); | 13796 ASSERT(!is_top_level_); |
14104 return closure.raw(); | 13797 return closure.raw(); |
14105 } | 13798 } |
14106 | 13799 |
14107 | |
14108 static String& BuildConstructorName(Thread* thread, | 13800 static String& BuildConstructorName(Thread* thread, |
14109 const String& type_class_name, | 13801 const String& type_class_name, |
14110 const String* named_constructor) { | 13802 const String* named_constructor) { |
14111 // By convention, the static function implementing a named constructor 'C' | 13803 // By convention, the static function implementing a named constructor 'C' |
14112 // for class 'A' is labeled 'A.C', and the static function implementing the | 13804 // for class 'A' is labeled 'A.C', and the static function implementing the |
14113 // unnamed constructor for class 'A' is labeled 'A.'. | 13805 // unnamed constructor for class 'A' is labeled 'A.'. |
14114 // This convention prevents users from explicitly calling constructors. | 13806 // This convention prevents users from explicitly calling constructors. |
14115 Zone* zone = thread->zone(); | 13807 Zone* zone = thread->zone(); |
14116 String& constructor_name = | 13808 String& constructor_name = |
14117 String::Handle(zone, Symbols::FromDot(thread, type_class_name)); | 13809 String::Handle(zone, Symbols::FromDot(thread, type_class_name)); |
14118 if (named_constructor != NULL) { | 13810 if (named_constructor != NULL) { |
14119 constructor_name = | 13811 constructor_name = |
14120 Symbols::FromConcat(thread, constructor_name, *named_constructor); | 13812 Symbols::FromConcat(thread, constructor_name, *named_constructor); |
14121 } | 13813 } |
14122 return constructor_name; | 13814 return constructor_name; |
14123 } | 13815 } |
14124 | 13816 |
14125 | |
14126 // Parse a primary expression of the form new T# or new T#m. | 13817 // Parse a primary expression of the form new T# or new T#m. |
14127 // Current token position is after the keyword new. Extracts the | 13818 // Current token position is after the keyword new. Extracts the |
14128 // anonymous or named constructor and type arguments. | 13819 // anonymous or named constructor and type arguments. |
14129 // Note that type type T has already been parsed before | 13820 // Note that type type T has already been parsed before |
14130 // (by ParseNewOperator()) and is guaranteed to be well-formed, | 13821 // (by ParseNewOperator()) and is guaranteed to be well-formed, |
14131 // and the constructor is known to exist. | 13822 // and the constructor is known to exist. |
14132 void Parser::ParseConstructorClosurization(Function* constructor, | 13823 void Parser::ParseConstructorClosurization(Function* constructor, |
14133 TypeArguments* type_arguments) { | 13824 TypeArguments* type_arguments) { |
14134 *constructor = Function::null(); | 13825 *constructor = Function::null(); |
14135 *type_arguments = TypeArguments::null(); | 13826 *type_arguments = TypeArguments::null(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14178 NULL, // bound_trail | 13869 NULL, // bound_trail |
14179 Heap::kOld); | 13870 Heap::kOld); |
14180 ASSERT(error.IsNull()); | 13871 ASSERT(error.IsNull()); |
14181 } | 13872 } |
14182 *type_arguments = type.arguments(); | 13873 *type_arguments = type.arguments(); |
14183 *constructor = constructor->RedirectionTarget(); | 13874 *constructor = constructor->RedirectionTarget(); |
14184 } | 13875 } |
14185 } | 13876 } |
14186 } | 13877 } |
14187 | 13878 |
14188 | |
14189 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 13879 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
14190 TRACE_PARSER("ParseNewOperator"); | 13880 TRACE_PARSER("ParseNewOperator"); |
14191 const TokenPosition new_pos = TokenPos(); | 13881 const TokenPosition new_pos = TokenPos(); |
14192 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 13882 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
14193 bool is_const = (op_kind == Token::kCONST); | 13883 bool is_const = (op_kind == Token::kCONST); |
14194 if (!IsIdentifier()) { | 13884 if (!IsIdentifier()) { |
14195 ReportError("type name expected"); | 13885 ReportError("type name expected"); |
14196 } | 13886 } |
14197 TokenPosition type_pos = TokenPos(); | 13887 TokenPosition type_pos = TokenPos(); |
14198 // Can't allocate const objects of a deferred type. | 13888 // Can't allocate const objects of a deferred type. |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14532 new_object = CreateConstructorCallNode(new_pos, type_arguments, constructor, | 14222 new_object = CreateConstructorCallNode(new_pos, type_arguments, constructor, |
14533 arguments); | 14223 arguments); |
14534 } | 14224 } |
14535 if (!type_bound.IsNull()) { | 14225 if (!type_bound.IsNull()) { |
14536 new_object = new (Z) AssignableNode(new_pos, new_object, type_bound, | 14226 new_object = new (Z) AssignableNode(new_pos, new_object, type_bound, |
14537 Symbols::FactoryResult()); | 14227 Symbols::FactoryResult()); |
14538 } | 14228 } |
14539 return new_object; | 14229 return new_object; |
14540 } | 14230 } |
14541 | 14231 |
14542 | |
14543 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { | 14232 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { |
14544 NoReloadScope no_reload_scope(isolate(), thread()); | 14233 NoReloadScope no_reload_scope(isolate(), thread()); |
14545 NoOOBMessageScope no_msg_scope(thread()); | 14234 NoOOBMessageScope no_msg_scope(thread()); |
14546 const Class& cls = | 14235 const Class& cls = |
14547 Class::Handle(Z, Library::LookupCoreClass(Symbols::StringBase())); | 14236 Class::Handle(Z, Library::LookupCoreClass(Symbols::StringBase())); |
14548 ASSERT(!cls.IsNull()); | 14237 ASSERT(!cls.IsNull()); |
14549 const Function& func = Function::Handle( | 14238 const Function& func = Function::Handle( |
14550 Z, cls.LookupStaticFunction( | 14239 Z, cls.LookupStaticFunction( |
14551 Library::PrivateCoreLibName(Symbols::Interpolate()))); | 14240 Library::PrivateCoreLibName(Symbols::Interpolate()))); |
14552 ASSERT(!func.IsNull()); | 14241 ASSERT(!func.IsNull()); |
(...skipping 15 matching lines...) Expand all Loading... |
14568 result = DartEntry::InvokeFunction(func, interpolate_arg); | 14257 result = DartEntry::InvokeFunction(func, interpolate_arg); |
14569 if (result.IsUnhandledException()) { | 14258 if (result.IsUnhandledException()) { |
14570 ReportError("%s", Error::Cast(result).ToErrorCString()); | 14259 ReportError("%s", Error::Cast(result).ToErrorCString()); |
14571 } | 14260 } |
14572 String& concatenated = String::ZoneHandle(Z); | 14261 String& concatenated = String::ZoneHandle(Z); |
14573 concatenated ^= result.raw(); | 14262 concatenated ^= result.raw(); |
14574 concatenated = Symbols::New(T, concatenated); | 14263 concatenated = Symbols::New(T, concatenated); |
14575 return concatenated; | 14264 return concatenated; |
14576 } | 14265 } |
14577 | 14266 |
14578 | |
14579 // A string literal consists of the concatenation of the next n tokens | 14267 // A string literal consists of the concatenation of the next n tokens |
14580 // that satisfy the EBNF grammar: | 14268 // that satisfy the EBNF grammar: |
14581 // literal = kSTRING {{ interpol } kSTRING } | 14269 // literal = kSTRING {{ interpol } kSTRING } |
14582 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 14270 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
14583 // In other words, the scanner breaks down interpolated strings so that | 14271 // In other words, the scanner breaks down interpolated strings so that |
14584 // a string literal always begins and ends with a kSTRING token. | 14272 // a string literal always begins and ends with a kSTRING token. |
14585 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 14273 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
14586 TRACE_PARSER("ParseStringLiteral"); | 14274 TRACE_PARSER("ParseStringLiteral"); |
14587 AstNode* primary = NULL; | 14275 AstNode* primary = NULL; |
14588 const TokenPosition literal_start = TokenPos(); | 14276 const TokenPosition literal_start = TokenPos(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14673 // find the value next time. | 14361 // find the value next time. |
14674 } | 14362 } |
14675 } else { | 14363 } else { |
14676 ArrayNode* values = new (Z) ArrayNode( | 14364 ArrayNode* values = new (Z) ArrayNode( |
14677 TokenPos(), Type::ZoneHandle(Z, Type::ArrayType()), values_list); | 14365 TokenPos(), Type::ZoneHandle(Z, Type::ArrayType()), values_list); |
14678 primary = new (Z) StringInterpolateNode(TokenPos(), values); | 14366 primary = new (Z) StringInterpolateNode(TokenPos(), values); |
14679 } | 14367 } |
14680 return primary; | 14368 return primary; |
14681 } | 14369 } |
14682 | 14370 |
14683 | |
14684 AstNode* Parser::ParsePrimary() { | 14371 AstNode* Parser::ParsePrimary() { |
14685 TRACE_PARSER("ParsePrimary"); | 14372 TRACE_PARSER("ParsePrimary"); |
14686 ASSERT(!is_top_level_); | 14373 ASSERT(!is_top_level_); |
14687 AstNode* primary = NULL; | 14374 AstNode* primary = NULL; |
14688 const Token::Kind token = CurrentToken(); | 14375 const Token::Kind token = CurrentToken(); |
14689 if (IsFunctionLiteral()) { | 14376 if (IsFunctionLiteral()) { |
14690 primary = ParseFunctionStatement(true); | 14377 primary = ParseFunctionStatement(true); |
14691 } else if (IsIdentifier()) { | 14378 } else if (IsIdentifier()) { |
14692 TokenPosition qual_ident_pos = TokenPos(); | 14379 TokenPosition qual_ident_pos = TokenPos(); |
14693 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 14380 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14886 ReportError("super call or super getter may not use ?."); | 14573 ReportError("super call or super getter may not use ?."); |
14887 } else { | 14574 } else { |
14888 primary = new (Z) PrimaryNode(super_pos, Symbols::Super()); | 14575 primary = new (Z) PrimaryNode(super_pos, Symbols::Super()); |
14889 } | 14576 } |
14890 } else { | 14577 } else { |
14891 UnexpectedToken(); | 14578 UnexpectedToken(); |
14892 } | 14579 } |
14893 return primary; | 14580 return primary; |
14894 } | 14581 } |
14895 | 14582 |
14896 | |
14897 // Evaluate expression in expr and return the value. The expression must | 14583 // Evaluate expression in expr and return the value. The expression must |
14898 // be a compile time constant. | 14584 // be a compile time constant. |
14899 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos, | 14585 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos, |
14900 AstNode* expr) { | 14586 AstNode* expr) { |
14901 NoReloadScope no_reload_scope(isolate(), thread()); | 14587 NoReloadScope no_reload_scope(isolate(), thread()); |
14902 NoOOBMessageScope no_msg_scope(thread()); | 14588 NoOOBMessageScope no_msg_scope(thread()); |
14903 if (expr->IsLiteralNode()) { | 14589 if (expr->IsLiteralNode()) { |
14904 return expr->AsLiteralNode()->literal(); | 14590 return expr->AsLiteralNode()->literal(); |
14905 } else if (expr->IsLoadLocalNode() && | 14591 } else if (expr->IsLoadLocalNode() && |
14906 expr->AsLoadLocalNode()->local().IsConst()) { | 14592 expr->AsLoadLocalNode()->local().IsConst()) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14944 "error evaluating constant expression"); | 14630 "error evaluating constant expression"); |
14945 } | 14631 } |
14946 ASSERT(result.IsInstance() || result.IsNull()); | 14632 ASSERT(result.IsInstance() || result.IsNull()); |
14947 value ^= result.raw(); | 14633 value ^= result.raw(); |
14948 value = TryCanonicalize(value, expr_pos); | 14634 value = TryCanonicalize(value, expr_pos); |
14949 CacheConstantValue(expr_pos, value); | 14635 CacheConstantValue(expr_pos, value); |
14950 return value; | 14636 return value; |
14951 } | 14637 } |
14952 } | 14638 } |
14953 | 14639 |
14954 | |
14955 void Parser::SkipFunctionLiteral() { | 14640 void Parser::SkipFunctionLiteral() { |
14956 if (IsIdentifier()) { | 14641 if (IsIdentifier()) { |
14957 if (LookaheadToken(1) != Token::kLPAREN) { | 14642 if (LookaheadToken(1) != Token::kLPAREN) { |
14958 SkipTypeOrFunctionType(true); | 14643 SkipTypeOrFunctionType(true); |
14959 } | 14644 } |
14960 ExpectIdentifier("function name expected"); | 14645 ExpectIdentifier("function name expected"); |
14961 } | 14646 } |
14962 if (CurrentToken() == Token::kLPAREN) { | 14647 if (CurrentToken() == Token::kLPAREN) { |
14963 SkipToMatchingParenthesis(); | 14648 SkipToMatchingParenthesis(); |
14964 } | 14649 } |
14965 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | 14650 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
14966 BoolScope allow_await(&this->await_is_keyword_, | 14651 BoolScope allow_await(&this->await_is_keyword_, |
14967 async_modifier != RawFunction::kNoModifier); | 14652 async_modifier != RawFunction::kNoModifier); |
14968 if (CurrentToken() == Token::kLBRACE) { | 14653 if (CurrentToken() == Token::kLBRACE) { |
14969 SkipBlock(); | 14654 SkipBlock(); |
14970 ExpectToken(Token::kRBRACE); | 14655 ExpectToken(Token::kRBRACE); |
14971 } else if (CurrentToken() == Token::kARROW) { | 14656 } else if (CurrentToken() == Token::kARROW) { |
14972 ConsumeToken(); | 14657 ConsumeToken(); |
14973 SkipExpr(); | 14658 SkipExpr(); |
14974 } | 14659 } |
14975 } | 14660 } |
14976 | 14661 |
14977 | |
14978 // Skips function/method/constructor/getter/setter preambles until the formal | 14662 // Skips function/method/constructor/getter/setter preambles until the formal |
14979 // parameter list. It is enough to skip the tokens, since we have already | 14663 // parameter list. It is enough to skip the tokens, since we have already |
14980 // previously parsed the function. | 14664 // previously parsed the function. |
14981 void Parser::SkipFunctionPreamble() { | 14665 void Parser::SkipFunctionPreamble() { |
14982 while (true) { | 14666 while (true) { |
14983 if (IsFunctionTypeSymbol()) { | 14667 if (IsFunctionTypeSymbol()) { |
14984 ConsumeToken(); | 14668 ConsumeToken(); |
14985 SkipTypeParameters(); | 14669 SkipTypeParameters(); |
14986 SkipToMatchingParenthesis(); | 14670 SkipToMatchingParenthesis(); |
14987 continue; | 14671 continue; |
(...skipping 16 matching lines...) Expand all Loading... |
15004 } | 14688 } |
15005 // Case: Getter. | 14689 // Case: Getter. |
15006 ConsumeToken(); // Parse away 'get'. | 14690 ConsumeToken(); // Parse away 'get'. |
15007 ConsumeToken(); // Parse away the getter name. | 14691 ConsumeToken(); // Parse away the getter name. |
15008 return; | 14692 return; |
15009 } | 14693 } |
15010 ConsumeToken(); // Can be static, factory, operator, void, ident, etc... | 14694 ConsumeToken(); // Can be static, factory, operator, void, ident, etc... |
15011 } | 14695 } |
15012 } | 14696 } |
15013 | 14697 |
15014 | |
15015 void Parser::SkipListLiteral() { | 14698 void Parser::SkipListLiteral() { |
15016 if (CurrentToken() == Token::kINDEX) { | 14699 if (CurrentToken() == Token::kINDEX) { |
15017 // Empty list literal. | 14700 // Empty list literal. |
15018 ConsumeToken(); | 14701 ConsumeToken(); |
15019 return; | 14702 return; |
15020 } | 14703 } |
15021 ExpectToken(Token::kLBRACK); | 14704 ExpectToken(Token::kLBRACK); |
15022 while (CurrentToken() != Token::kRBRACK) { | 14705 while (CurrentToken() != Token::kRBRACK) { |
15023 SkipNestedExpr(); | 14706 SkipNestedExpr(); |
15024 if (CurrentToken() == Token::kCOMMA) { | 14707 if (CurrentToken() == Token::kCOMMA) { |
15025 ConsumeToken(); | 14708 ConsumeToken(); |
15026 } else { | 14709 } else { |
15027 break; | 14710 break; |
15028 } | 14711 } |
15029 } | 14712 } |
15030 ExpectToken(Token::kRBRACK); | 14713 ExpectToken(Token::kRBRACK); |
15031 } | 14714 } |
15032 | 14715 |
15033 | |
15034 void Parser::SkipMapLiteral() { | 14716 void Parser::SkipMapLiteral() { |
15035 ExpectToken(Token::kLBRACE); | 14717 ExpectToken(Token::kLBRACE); |
15036 while (CurrentToken() != Token::kRBRACE) { | 14718 while (CurrentToken() != Token::kRBRACE) { |
15037 SkipNestedExpr(); | 14719 SkipNestedExpr(); |
15038 ExpectToken(Token::kCOLON); | 14720 ExpectToken(Token::kCOLON); |
15039 SkipNestedExpr(); | 14721 SkipNestedExpr(); |
15040 if (CurrentToken() == Token::kCOMMA) { | 14722 if (CurrentToken() == Token::kCOMMA) { |
15041 ConsumeToken(); | 14723 ConsumeToken(); |
15042 } else { | 14724 } else { |
15043 break; | 14725 break; |
15044 } | 14726 } |
15045 } | 14727 } |
15046 ExpectToken(Token::kRBRACE); | 14728 ExpectToken(Token::kRBRACE); |
15047 } | 14729 } |
15048 | 14730 |
15049 | |
15050 void Parser::SkipActualParameters() { | 14731 void Parser::SkipActualParameters() { |
15051 if (CurrentToken() == Token::kLT) { | 14732 if (CurrentToken() == Token::kLT) { |
15052 SkipTypeArguments(); | 14733 SkipTypeArguments(); |
15053 } | 14734 } |
15054 ExpectToken(Token::kLPAREN); | 14735 ExpectToken(Token::kLPAREN); |
15055 while (CurrentToken() != Token::kRPAREN) { | 14736 while (CurrentToken() != Token::kRPAREN) { |
15056 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 14737 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
15057 // Named actual parameter. | 14738 // Named actual parameter. |
15058 ConsumeToken(); | 14739 ConsumeToken(); |
15059 ConsumeToken(); | 14740 ConsumeToken(); |
15060 } | 14741 } |
15061 SkipNestedExpr(); | 14742 SkipNestedExpr(); |
15062 if (CurrentToken() == Token::kCOMMA) { | 14743 if (CurrentToken() == Token::kCOMMA) { |
15063 ConsumeToken(); | 14744 ConsumeToken(); |
15064 } | 14745 } |
15065 } | 14746 } |
15066 ExpectToken(Token::kRPAREN); | 14747 ExpectToken(Token::kRPAREN); |
15067 } | 14748 } |
15068 | 14749 |
15069 | |
15070 void Parser::SkipCompoundLiteral() { | 14750 void Parser::SkipCompoundLiteral() { |
15071 if (CurrentToken() == Token::kLT) { | 14751 if (CurrentToken() == Token::kLT) { |
15072 SkipTypeArguments(); | 14752 SkipTypeArguments(); |
15073 } | 14753 } |
15074 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { | 14754 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { |
15075 SkipListLiteral(); | 14755 SkipListLiteral(); |
15076 } else if (CurrentToken() == Token::kLBRACE) { | 14756 } else if (CurrentToken() == Token::kLBRACE) { |
15077 SkipMapLiteral(); | 14757 SkipMapLiteral(); |
15078 } | 14758 } |
15079 } | 14759 } |
15080 | 14760 |
15081 | |
15082 void Parser::SkipSymbolLiteral() { | 14761 void Parser::SkipSymbolLiteral() { |
15083 ConsumeToken(); // Hash sign. | 14762 ConsumeToken(); // Hash sign. |
15084 if (IsIdentifier()) { | 14763 if (IsIdentifier()) { |
15085 ConsumeToken(); | 14764 ConsumeToken(); |
15086 while (CurrentToken() == Token::kPERIOD) { | 14765 while (CurrentToken() == Token::kPERIOD) { |
15087 ConsumeToken(); | 14766 ConsumeToken(); |
15088 ExpectIdentifier("identifier expected"); | 14767 ExpectIdentifier("identifier expected"); |
15089 } | 14768 } |
15090 } else if (Token::CanBeOverloaded(CurrentToken())) { | 14769 } else if (Token::CanBeOverloaded(CurrentToken())) { |
15091 ConsumeToken(); | 14770 ConsumeToken(); |
15092 } else { | 14771 } else { |
15093 UnexpectedToken(); | 14772 UnexpectedToken(); |
15094 } | 14773 } |
15095 } | 14774 } |
15096 | 14775 |
15097 | |
15098 void Parser::SkipNewOperator() { | 14776 void Parser::SkipNewOperator() { |
15099 ConsumeToken(); // Skip new or const keyword. | 14777 ConsumeToken(); // Skip new or const keyword. |
15100 if (IsIdentifier()) { | 14778 if (IsIdentifier()) { |
15101 SkipType(false); | 14779 SkipType(false); |
15102 if (CurrentToken() == Token::kPERIOD) { | 14780 if (CurrentToken() == Token::kPERIOD) { |
15103 ConsumeToken(); | 14781 ConsumeToken(); |
15104 ExpectIdentifier("identifier expected"); | 14782 ExpectIdentifier("identifier expected"); |
15105 } else if (CurrentToken() == Token::kHASH) { | 14783 } else if (CurrentToken() == Token::kHASH) { |
15106 ConsumeToken(); | 14784 ConsumeToken(); |
15107 if (IsIdentifier()) { | 14785 if (IsIdentifier()) { |
15108 ConsumeToken(); | 14786 ConsumeToken(); |
15109 } | 14787 } |
15110 return; | 14788 return; |
15111 } | 14789 } |
15112 if (CurrentToken() == Token::kLPAREN) { | 14790 if (CurrentToken() == Token::kLPAREN) { |
15113 SkipActualParameters(); | 14791 SkipActualParameters(); |
15114 return; | 14792 return; |
15115 } | 14793 } |
15116 } | 14794 } |
15117 } | 14795 } |
15118 | 14796 |
15119 | |
15120 void Parser::SkipStringLiteral() { | 14797 void Parser::SkipStringLiteral() { |
15121 ASSERT(CurrentToken() == Token::kSTRING); | 14798 ASSERT(CurrentToken() == Token::kSTRING); |
15122 while (CurrentToken() == Token::kSTRING) { | 14799 while (CurrentToken() == Token::kSTRING) { |
15123 ConsumeToken(); | 14800 ConsumeToken(); |
15124 while (true) { | 14801 while (true) { |
15125 if (CurrentToken() == Token::kINTERPOL_VAR) { | 14802 if (CurrentToken() == Token::kINTERPOL_VAR) { |
15126 ConsumeToken(); | 14803 ConsumeToken(); |
15127 } else if (CurrentToken() == Token::kINTERPOL_START) { | 14804 } else if (CurrentToken() == Token::kINTERPOL_START) { |
15128 ConsumeToken(); | 14805 ConsumeToken(); |
15129 const bool saved_mode = SetAllowFunctionLiterals(true); | 14806 const bool saved_mode = SetAllowFunctionLiterals(true); |
15130 SkipExpr(); | 14807 SkipExpr(); |
15131 SetAllowFunctionLiterals(saved_mode); | 14808 SetAllowFunctionLiterals(saved_mode); |
15132 ExpectToken(Token::kINTERPOL_END); | 14809 ExpectToken(Token::kINTERPOL_END); |
15133 } else { | 14810 } else { |
15134 break; | 14811 break; |
15135 } | 14812 } |
15136 } | 14813 } |
15137 } | 14814 } |
15138 } | 14815 } |
15139 | 14816 |
15140 | |
15141 void Parser::SkipPrimary() { | 14817 void Parser::SkipPrimary() { |
15142 if (IsFunctionLiteral()) { | 14818 if (IsFunctionLiteral()) { |
15143 SkipFunctionLiteral(); | 14819 SkipFunctionLiteral(); |
15144 return; | 14820 return; |
15145 } | 14821 } |
15146 switch (CurrentToken()) { | 14822 switch (CurrentToken()) { |
15147 case Token::kTHIS: | 14823 case Token::kTHIS: |
15148 case Token::kSUPER: | 14824 case Token::kSUPER: |
15149 case Token::kNULL: | 14825 case Token::kNULL: |
15150 case Token::kTRUE: | 14826 case Token::kTRUE: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15191 if (IsIdentifier()) { | 14867 if (IsIdentifier()) { |
15192 ConsumeToken(); // Handle pseudo-keyword identifiers. | 14868 ConsumeToken(); // Handle pseudo-keyword identifiers. |
15193 } else { | 14869 } else { |
15194 UnexpectedToken(); | 14870 UnexpectedToken(); |
15195 UNREACHABLE(); | 14871 UNREACHABLE(); |
15196 } | 14872 } |
15197 break; | 14873 break; |
15198 } | 14874 } |
15199 } | 14875 } |
15200 | 14876 |
15201 | |
15202 void Parser::SkipSelectors() { | 14877 void Parser::SkipSelectors() { |
15203 while (true) { | 14878 while (true) { |
15204 const Token::Kind current_token = CurrentToken(); | 14879 const Token::Kind current_token = CurrentToken(); |
15205 if (current_token == Token::kCASCADE) { | 14880 if (current_token == Token::kCASCADE) { |
15206 ConsumeToken(); | 14881 ConsumeToken(); |
15207 if (CurrentToken() == Token::kLBRACK) { | 14882 if (CurrentToken() == Token::kLBRACK) { |
15208 continue; // Consume [ in next loop iteration. | 14883 continue; // Consume [ in next loop iteration. |
15209 } else { | 14884 } else { |
15210 ExpectIdentifier("identifier or [ expected after .."); | 14885 ExpectIdentifier("identifier or [ expected after .."); |
15211 } | 14886 } |
(...skipping 25 matching lines...) Expand all Loading... |
15237 } else { | 14912 } else { |
15238 ReportError("identifier or operator expected"); | 14913 ReportError("identifier or operator expected"); |
15239 } | 14914 } |
15240 } | 14915 } |
15241 SkipSelectors(); | 14916 SkipSelectors(); |
15242 if (IsIncrementOperator(CurrentToken())) { | 14917 if (IsIncrementOperator(CurrentToken())) { |
15243 ConsumeToken(); | 14918 ConsumeToken(); |
15244 } | 14919 } |
15245 } | 14920 } |
15246 | 14921 |
15247 | |
15248 void Parser::SkipUnaryExpr() { | 14922 void Parser::SkipUnaryExpr() { |
15249 if (IsPrefixOperator(CurrentToken()) || IsIncrementOperator(CurrentToken()) || | 14923 if (IsPrefixOperator(CurrentToken()) || IsIncrementOperator(CurrentToken()) || |
15250 IsAwaitKeyword()) { | 14924 IsAwaitKeyword()) { |
15251 ConsumeToken(); | 14925 ConsumeToken(); |
15252 SkipUnaryExpr(); | 14926 SkipUnaryExpr(); |
15253 } else { | 14927 } else { |
15254 SkipPostfixExpr(); | 14928 SkipPostfixExpr(); |
15255 } | 14929 } |
15256 } | 14930 } |
15257 | 14931 |
15258 | |
15259 void Parser::SkipBinaryExpr() { | 14932 void Parser::SkipBinaryExpr() { |
15260 SkipUnaryExpr(); | 14933 SkipUnaryExpr(); |
15261 const int min_prec = Token::Precedence(Token::kIFNULL); | 14934 const int min_prec = Token::Precedence(Token::kIFNULL); |
15262 const int max_prec = Token::Precedence(Token::kMUL); | 14935 const int max_prec = Token::Precedence(Token::kMUL); |
15263 while (((min_prec <= Token::Precedence(CurrentToken())) && | 14936 while (((min_prec <= Token::Precedence(CurrentToken())) && |
15264 (Token::Precedence(CurrentToken()) <= max_prec))) { | 14937 (Token::Precedence(CurrentToken()) <= max_prec))) { |
15265 if (CurrentToken() == Token::kIS) { | 14938 if (CurrentToken() == Token::kIS) { |
15266 ConsumeToken(); | 14939 ConsumeToken(); |
15267 if (CurrentToken() == Token::kNOT) { | 14940 if (CurrentToken() == Token::kNOT) { |
15268 ConsumeToken(); | 14941 ConsumeToken(); |
15269 } | 14942 } |
15270 SkipTypeOrFunctionType(false); | 14943 SkipTypeOrFunctionType(false); |
15271 } else if (CurrentToken() == Token::kAS) { | 14944 } else if (CurrentToken() == Token::kAS) { |
15272 ConsumeToken(); | 14945 ConsumeToken(); |
15273 SkipTypeOrFunctionType(false); | 14946 SkipTypeOrFunctionType(false); |
15274 } else { | 14947 } else { |
15275 ConsumeToken(); | 14948 ConsumeToken(); |
15276 SkipUnaryExpr(); | 14949 SkipUnaryExpr(); |
15277 } | 14950 } |
15278 } | 14951 } |
15279 } | 14952 } |
15280 | 14953 |
15281 | |
15282 void Parser::SkipConditionalExpr() { | 14954 void Parser::SkipConditionalExpr() { |
15283 SkipBinaryExpr(); | 14955 SkipBinaryExpr(); |
15284 if (CurrentToken() == Token::kCONDITIONAL) { | 14956 if (CurrentToken() == Token::kCONDITIONAL) { |
15285 ConsumeToken(); | 14957 ConsumeToken(); |
15286 SkipExpr(); | 14958 SkipExpr(); |
15287 ExpectToken(Token::kCOLON); | 14959 ExpectToken(Token::kCOLON); |
15288 SkipExpr(); | 14960 SkipExpr(); |
15289 } | 14961 } |
15290 } | 14962 } |
15291 | 14963 |
15292 | |
15293 void Parser::SkipExpr() { | 14964 void Parser::SkipExpr() { |
15294 while (CurrentToken() == Token::kTHROW) { | 14965 while (CurrentToken() == Token::kTHROW) { |
15295 ConsumeToken(); | 14966 ConsumeToken(); |
15296 } | 14967 } |
15297 SkipConditionalExpr(); | 14968 SkipConditionalExpr(); |
15298 if (CurrentToken() == Token::kCASCADE) { | 14969 if (CurrentToken() == Token::kCASCADE) { |
15299 SkipSelectors(); | 14970 SkipSelectors(); |
15300 } | 14971 } |
15301 if (Token::IsAssignmentOperator(CurrentToken())) { | 14972 if (Token::IsAssignmentOperator(CurrentToken())) { |
15302 ConsumeToken(); | 14973 ConsumeToken(); |
15303 SkipExpr(); | 14974 SkipExpr(); |
15304 } | 14975 } |
15305 } | 14976 } |
15306 | 14977 |
15307 | |
15308 void Parser::SkipNestedExpr() { | 14978 void Parser::SkipNestedExpr() { |
15309 const bool saved_mode = SetAllowFunctionLiterals(true); | 14979 const bool saved_mode = SetAllowFunctionLiterals(true); |
15310 SkipExpr(); | 14980 SkipExpr(); |
15311 SetAllowFunctionLiterals(saved_mode); | 14981 SetAllowFunctionLiterals(saved_mode); |
15312 } | 14982 } |
15313 | 14983 |
15314 | |
15315 void Parser::SkipQualIdent() { | 14984 void Parser::SkipQualIdent() { |
15316 ASSERT(IsIdentifier()); | 14985 ASSERT(IsIdentifier()); |
15317 ConsumeToken(); | 14986 ConsumeToken(); |
15318 if (CurrentToken() == Token::kPERIOD) { | 14987 if (CurrentToken() == Token::kPERIOD) { |
15319 ConsumeToken(); // Consume the kPERIOD token. | 14988 ConsumeToken(); // Consume the kPERIOD token. |
15320 ExpectIdentifier("identifier expected after '.'"); | 14989 ExpectIdentifier("identifier expected after '.'"); |
15321 } | 14990 } |
15322 } | 14991 } |
15323 | 14992 |
15324 } // namespace dart | 14993 } // namespace dart |
15325 | 14994 |
15326 | |
15327 #else // DART_PRECOMPILED_RUNTIME | 14995 #else // DART_PRECOMPILED_RUNTIME |
15328 | 14996 |
15329 | |
15330 namespace dart { | 14997 namespace dart { |
15331 | 14998 |
15332 void ParsedFunction::AddToGuardedFields(const Field* field) const { | 14999 void ParsedFunction::AddToGuardedFields(const Field* field) const { |
15333 UNREACHABLE(); | 15000 UNREACHABLE(); |
15334 } | 15001 } |
15335 | 15002 |
15336 | |
15337 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { | 15003 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { |
15338 UNREACHABLE(); | 15004 UNREACHABLE(); |
15339 return NULL; | 15005 return NULL; |
15340 } | 15006 } |
15341 | 15007 |
15342 | |
15343 LocalVariable* ParsedFunction::EnsureExpressionTemp() { | 15008 LocalVariable* ParsedFunction::EnsureExpressionTemp() { |
15344 UNREACHABLE(); | 15009 UNREACHABLE(); |
15345 return NULL; | 15010 return NULL; |
15346 } | 15011 } |
15347 | 15012 |
15348 | |
15349 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 15013 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
15350 UNREACHABLE(); | 15014 UNREACHABLE(); |
15351 } | 15015 } |
15352 | 15016 |
15353 | |
15354 void ParsedFunction::SetRegExpCompileData( | 15017 void ParsedFunction::SetRegExpCompileData( |
15355 RegExpCompileData* regexp_compile_data) { | 15018 RegExpCompileData* regexp_compile_data) { |
15356 UNREACHABLE(); | 15019 UNREACHABLE(); |
15357 } | 15020 } |
15358 | 15021 |
15359 | |
15360 void ParsedFunction::AllocateVariables() { | 15022 void ParsedFunction::AllocateVariables() { |
15361 UNREACHABLE(); | 15023 UNREACHABLE(); |
15362 } | 15024 } |
15363 | 15025 |
15364 | |
15365 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 15026 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
15366 UNREACHABLE(); | 15027 UNREACHABLE(); |
15367 } | 15028 } |
15368 | 15029 |
15369 | |
15370 void ParsedFunction::Bailout(const char* origin, const char* reason) const { | 15030 void ParsedFunction::Bailout(const char* origin, const char* reason) const { |
15371 UNREACHABLE(); | 15031 UNREACHABLE(); |
15372 } | 15032 } |
15373 | 15033 |
15374 | |
15375 void Parser::ParseCompilationUnit(const Library& library, | 15034 void Parser::ParseCompilationUnit(const Library& library, |
15376 const Script& script) { | 15035 const Script& script) { |
15377 UNREACHABLE(); | 15036 UNREACHABLE(); |
15378 } | 15037 } |
15379 | 15038 |
15380 | |
15381 void Parser::ParseClass(const Class& cls) { | 15039 void Parser::ParseClass(const Class& cls) { |
15382 UNREACHABLE(); | 15040 UNREACHABLE(); |
15383 } | 15041 } |
15384 | 15042 |
15385 | |
15386 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 15043 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
15387 UNREACHABLE(); | 15044 UNREACHABLE(); |
15388 return Object::null(); | 15045 return Object::null(); |
15389 } | 15046 } |
15390 | 15047 |
15391 | |
15392 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 15048 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
15393 UNREACHABLE(); | 15049 UNREACHABLE(); |
15394 } | 15050 } |
15395 | 15051 |
15396 | |
15397 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 15052 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
15398 UNREACHABLE(); | 15053 UNREACHABLE(); |
15399 return Object::null(); | 15054 return Object::null(); |
15400 } | 15055 } |
15401 | 15056 |
15402 | |
15403 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 15057 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
15404 UNREACHABLE(); | 15058 UNREACHABLE(); |
15405 return NULL; | 15059 return NULL; |
15406 } | 15060 } |
15407 | 15061 |
15408 | |
15409 void Parser::InsertCachedConstantValue(const Script& script, | 15062 void Parser::InsertCachedConstantValue(const Script& script, |
15410 TokenPosition token_pos, | 15063 TokenPosition token_pos, |
15411 const Instance& value) { | 15064 const Instance& value) { |
15412 UNREACHABLE(); | 15065 UNREACHABLE(); |
15413 } | 15066 } |
15414 | 15067 |
15415 | |
15416 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 15068 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
15417 TokenPosition call_pos, | 15069 TokenPosition call_pos, |
15418 const String& function_name, | 15070 const String& function_name, |
15419 const ArgumentListNode& function_args, | 15071 const ArgumentListNode& function_args, |
15420 const LocalVariable* temp_for_last_arg, | 15072 const LocalVariable* temp_for_last_arg, |
15421 bool is_super_invocation) { | 15073 bool is_super_invocation) { |
15422 UNREACHABLE(); | 15074 UNREACHABLE(); |
15423 return NULL; | 15075 return NULL; |
15424 } | 15076 } |
15425 | 15077 |
15426 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, | 15078 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, |
15427 TokenPosition* start, | 15079 TokenPosition* start, |
15428 TokenPosition* end) { | 15080 TokenPosition* end) { |
15429 UNREACHABLE(); | 15081 UNREACHABLE(); |
15430 return false; | 15082 return false; |
15431 } | 15083 } |
15432 | 15084 |
15433 | |
15434 } // namespace dart | 15085 } // namespace dart |
15435 | 15086 |
15436 #endif // DART_PRECOMPILED_RUNTIME | 15087 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |