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 29 matching lines...) Expand all Loading... |
40 #include "vm/timer.h" | 40 #include "vm/timer.h" |
41 #include "vm/zone.h" | 41 #include "vm/zone.h" |
42 | 42 |
43 namespace dart { | 43 namespace dart { |
44 | 44 |
45 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); | 45 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); |
46 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 46 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
47 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 47 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
48 // TODO(floitsch): remove the conditional-directive flag, once we publicly | 48 // TODO(floitsch): remove the conditional-directive flag, once we publicly |
49 // committed to the current version. | 49 // committed to the current version. |
50 DEFINE_FLAG(bool, conditional_directives, true, | 50 DEFINE_FLAG(bool, |
51 "Enable conditional directives"); | 51 conditional_directives, |
| 52 true, |
| 53 "Enable conditional directives"); |
52 DEFINE_FLAG(bool, generic_method_syntax, false, "Enable generic functions."); | 54 DEFINE_FLAG(bool, generic_method_syntax, false, "Enable generic functions."); |
53 DEFINE_FLAG(bool, initializing_formal_access, false, | 55 DEFINE_FLAG(bool, |
54 "Make initializing formal parameters visible in initializer list."); | 56 initializing_formal_access, |
55 DEFINE_FLAG(bool, warn_super, false, | 57 false, |
56 "Warning if super initializer not last in initializer list."); | 58 "Make initializing formal parameters visible in initializer list."); |
| 59 DEFINE_FLAG(bool, |
| 60 warn_super, |
| 61 false, |
| 62 "Warning if super initializer not last in initializer list."); |
57 DEFINE_FLAG(bool, warn_patch, false, "Warn on old-style patch syntax."); | 63 DEFINE_FLAG(bool, warn_patch, false, "Warn on old-style patch syntax."); |
58 DEFINE_FLAG(bool, await_is_keyword, false, | 64 DEFINE_FLAG( |
| 65 bool, |
| 66 await_is_keyword, |
| 67 false, |
59 "await and yield are treated as proper keywords in synchronous code."); | 68 "await and yield are treated as proper keywords in synchronous code."); |
60 DEFINE_FLAG(bool, assert_initializer, false, | 69 DEFINE_FLAG(bool, |
61 "Allow asserts in initializer lists."); | 70 assert_initializer, |
| 71 false, |
| 72 "Allow asserts in initializer lists."); |
62 | 73 |
63 DECLARE_FLAG(bool, profile_vm); | 74 DECLARE_FLAG(bool, profile_vm); |
64 DECLARE_FLAG(bool, trace_service); | 75 DECLARE_FLAG(bool, trace_service); |
65 DECLARE_FLAG(bool, ignore_patch_signature_mismatch); | 76 DECLARE_FLAG(bool, ignore_patch_signature_mismatch); |
66 | 77 |
67 // Quick access to the current thread, isolate and zone. | 78 // Quick access to the current thread, isolate and zone. |
68 #define T (thread()) | 79 #define T (thread()) |
69 #define I (isolate()) | 80 #define I (isolate()) |
70 #define Z (zone()) | 81 #define Z (zone()) |
71 | 82 |
72 // Quick synthetic token position. | 83 // Quick synthetic token position. |
73 #define ST(token_pos) ((token_pos).ToSynthetic()) | 84 #define ST(token_pos) ((token_pos).ToSynthetic()) |
74 | 85 |
75 #if defined(DEBUG) | 86 #if defined(DEBUG) |
76 class TraceParser : public ValueObject { | 87 class TraceParser : public ValueObject { |
77 public: | 88 public: |
78 TraceParser(TokenPosition token_pos, | 89 TraceParser(TokenPosition token_pos, |
79 const Script& script, | 90 const Script& script, |
80 intptr_t* trace_indent, | 91 intptr_t* trace_indent, |
81 const char* msg) { | 92 const char* msg) { |
82 indent_ = trace_indent; | 93 indent_ = trace_indent; |
83 if (FLAG_trace_parser) { | 94 if (FLAG_trace_parser) { |
84 // Skips tracing of bootstrap libraries. | 95 // Skips tracing of bootstrap libraries. |
85 if (script.HasSource()) { | 96 if (script.HasSource()) { |
86 intptr_t line, column; | 97 intptr_t line, column; |
87 script.GetTokenLocation(token_pos, &line, &column); | 98 script.GetTokenLocation(token_pos, &line, &column); |
88 PrintIndent(); | 99 PrintIndent(); |
89 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", | 100 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", msg, line, |
90 msg, line, column, token_pos.value()); | 101 column, token_pos.value()); |
91 } | 102 } |
92 (*indent_)++; | 103 (*indent_)++; |
93 } | 104 } |
94 } | 105 } |
95 ~TraceParser() { | 106 ~TraceParser() { |
96 if (FLAG_trace_parser) { | 107 if (FLAG_trace_parser) { |
97 (*indent_)--; | 108 (*indent_)--; |
98 ASSERT(*indent_ >= 0); | 109 ASSERT(*indent_ >= 0); |
99 } | 110 } |
100 } | 111 } |
101 | 112 |
102 private: | 113 private: |
103 void PrintIndent() { | 114 void PrintIndent() { |
104 for (intptr_t i = 0; i < *indent_; i++) { OS::Print(". "); } | 115 for (intptr_t i = 0; i < *indent_; i++) { |
| 116 OS::Print(". "); |
| 117 } |
105 } | 118 } |
106 intptr_t* indent_; | 119 intptr_t* indent_; |
107 }; | 120 }; |
108 | 121 |
109 | 122 |
110 #define TRACE_PARSER(s) \ | 123 #define TRACE_PARSER(s) \ |
111 TraceParser __p__(this->TokenPos(), this->script_, &this->trace_indent_, s) | 124 TraceParser __p__(this->TokenPos(), this->script_, &this->trace_indent_, s) |
112 | 125 |
113 #else // not DEBUG | 126 #else // not DEBUG |
114 #define TRACE_PARSER(s) | 127 #define TRACE_PARSER(s) |
115 #endif // DEBUG | 128 #endif // DEBUG |
116 | 129 |
117 | 130 |
118 class BoolScope : public ValueObject { | 131 class BoolScope : public ValueObject { |
119 public: | 132 public: |
120 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) { | 133 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) { |
121 *_addr = new_value; | 134 *_addr = new_value; |
122 } | 135 } |
123 ~BoolScope() { | 136 ~BoolScope() { *_addr = _saved_value; } |
124 *_addr = _saved_value; | |
125 } | |
126 | 137 |
127 private: | 138 private: |
128 bool* _addr; | 139 bool* _addr; |
129 bool _saved_value; | 140 bool _saved_value; |
130 }; | 141 }; |
131 | 142 |
132 | 143 |
133 // Helper class to save and restore token position. | 144 // Helper class to save and restore token position. |
134 class Parser::TokenPosScope : public ValueObject { | 145 class Parser::TokenPosScope : public ValueObject { |
135 public: | 146 public: |
136 explicit TokenPosScope(Parser *p) : p_(p) { | 147 explicit TokenPosScope(Parser* p) : p_(p) { saved_pos_ = p_->TokenPos(); } |
137 saved_pos_ = p_->TokenPos(); | 148 TokenPosScope(Parser* p, TokenPosition pos) : p_(p), saved_pos_(pos) {} |
138 } | 149 ~TokenPosScope() { p_->SetPosition(saved_pos_); } |
139 TokenPosScope(Parser *p, TokenPosition pos) : p_(p), saved_pos_(pos) { | |
140 } | |
141 ~TokenPosScope() { | |
142 p_->SetPosition(saved_pos_); | |
143 } | |
144 | 150 |
145 private: | 151 private: |
146 Parser* p_; | 152 Parser* p_; |
147 TokenPosition saved_pos_; | 153 TokenPosition saved_pos_; |
148 DISALLOW_COPY_AND_ASSIGN(TokenPosScope); | 154 DISALLOW_COPY_AND_ASSIGN(TokenPosScope); |
149 }; | 155 }; |
150 | 156 |
151 | 157 |
152 class RecursionChecker : public ValueObject { | 158 class RecursionChecker : public ValueObject { |
153 public: | 159 public: |
154 explicit RecursionChecker(Parser* p) : parser_(p) { | 160 explicit RecursionChecker(Parser* p) : parser_(p) { |
155 parser_->recursion_counter_++; | 161 parser_->recursion_counter_++; |
156 // No need to check the stack unless the parser is in an unusually deep | 162 // No need to check the stack unless the parser is in an unusually deep |
157 // recurive state. Thus, we omit the more expensive stack checks in | 163 // recurive state. Thus, we omit the more expensive stack checks in |
158 // the common case. | 164 // the common case. |
159 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. | 165 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. |
160 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { | 166 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { |
161 parser_->CheckStack(); | 167 parser_->CheckStack(); |
162 } | 168 } |
163 } | 169 } |
164 ~RecursionChecker() { | 170 ~RecursionChecker() { parser_->recursion_counter_--; } |
165 parser_->recursion_counter_--; | |
166 } | |
167 | 171 |
168 private: | 172 private: |
169 Parser* parser_; | 173 Parser* parser_; |
170 }; | 174 }; |
171 | 175 |
172 | 176 |
173 static RawTypeArguments* NewTypeArguments( | 177 static RawTypeArguments* NewTypeArguments( |
174 const GrowableArray<AbstractType*>& objs) { | 178 const GrowableArray<AbstractType*>& objs) { |
175 const TypeArguments& a = | 179 const TypeArguments& a = |
176 TypeArguments::Handle(TypeArguments::New(objs.length())); | 180 TypeArguments::Handle(TypeArguments::New(objs.length())); |
(...skipping 13 matching lines...) Expand all Loading... |
190 } | 194 } |
191 | 195 |
192 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { | 196 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { |
193 const Field* other = (*guarded_fields_)[j]; | 197 const Field* other = (*guarded_fields_)[j]; |
194 if (field->Original() == other->Original()) { | 198 if (field->Original() == other->Original()) { |
195 // Abort background compilation early if the guarded state of this field | 199 // Abort background compilation early if the guarded state of this field |
196 // has changed during compilation. We will not be able to commit | 200 // has changed during compilation. We will not be able to commit |
197 // the resulting code anyway. | 201 // the resulting code anyway. |
198 if (Compiler::IsBackgroundCompilation()) { | 202 if (Compiler::IsBackgroundCompilation()) { |
199 if (!other->IsConsistentWith(*field)) { | 203 if (!other->IsConsistentWith(*field)) { |
200 Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId, | 204 Compiler::AbortBackgroundCompilation( |
| 205 Thread::kNoDeoptId, |
201 "Field's guarded state changed during compilation"); | 206 "Field's guarded state changed during compilation"); |
202 } | 207 } |
203 } | 208 } |
204 return; | 209 return; |
205 } | 210 } |
206 } | 211 } |
207 | 212 |
208 // Note: the list of guarded fields must contain copies during background | 213 // Note: the list of guarded fields must contain copies during background |
209 // compilation because we will look at their guarded_cid when copying | 214 // compilation because we will look at their guarded_cid when copying |
210 // the array of guarded fields from callee into the caller during | 215 // the array of guarded fields from callee into the caller during |
211 // inlining. | 216 // inlining. |
212 ASSERT(!field->IsOriginal() || Thread::Current()->IsMutatorThread()); | 217 ASSERT(!field->IsOriginal() || Thread::Current()->IsMutatorThread()); |
213 guarded_fields_->Add(&Field::ZoneHandle(Z, field->raw())); | 218 guarded_fields_->Add(&Field::ZoneHandle(Z, field->raw())); |
214 } | 219 } |
215 | 220 |
216 | 221 |
217 void ParsedFunction::Bailout(const char* origin, const char* reason) const { | 222 void ParsedFunction::Bailout(const char* origin, const char* reason) const { |
218 Report::MessageF(Report::kBailout, | 223 Report::MessageF(Report::kBailout, Script::Handle(function_.script()), |
219 Script::Handle(function_.script()), | 224 function_.token_pos(), Report::AtLocation, |
220 function_.token_pos(), | 225 "%s Bailout in %s: %s", origin, |
221 Report::AtLocation, | 226 String::Handle(function_.name()).ToCString(), reason); |
222 "%s Bailout in %s: %s", | |
223 origin, | |
224 String::Handle(function_.name()).ToCString(), | |
225 reason); | |
226 UNREACHABLE(); | 227 UNREACHABLE(); |
227 } | 228 } |
228 | 229 |
229 | 230 |
230 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { | 231 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { |
231 if (kernel_scopes_ == NULL) { | 232 if (kernel_scopes_ == NULL) { |
232 kernel::TreeNode* node = NULL; | 233 kernel::TreeNode* node = NULL; |
233 if (function().kernel_function() != NULL) { | 234 if (function().kernel_function() != NULL) { |
234 node = static_cast<kernel::TreeNode*>(function().kernel_function()); | 235 node = static_cast<kernel::TreeNode*>(function().kernel_function()); |
235 } | 236 } |
236 kernel::ScopeBuilder builder(this, node); | 237 kernel::ScopeBuilder builder(this, node); |
237 kernel_scopes_ = builder.BuildScopes(); | 238 kernel_scopes_ = builder.BuildScopes(); |
238 } | 239 } |
239 return kernel_scopes_; | 240 return kernel_scopes_; |
240 } | 241 } |
241 | 242 |
242 | 243 |
243 LocalVariable* ParsedFunction::EnsureExpressionTemp() { | 244 LocalVariable* ParsedFunction::EnsureExpressionTemp() { |
244 if (!has_expression_temp_var()) { | 245 if (!has_expression_temp_var()) { |
245 LocalVariable* temp = | 246 LocalVariable* temp = |
246 new (Z) LocalVariable(function_.token_pos(), | 247 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), |
247 function_.token_pos(), | 248 Symbols::ExprTemp(), Object::dynamic_type()); |
248 Symbols::ExprTemp(), | |
249 Object::dynamic_type()); | |
250 ASSERT(temp != NULL); | 249 ASSERT(temp != NULL); |
251 set_expression_temp_var(temp); | 250 set_expression_temp_var(temp); |
252 } | 251 } |
253 ASSERT(has_expression_temp_var()); | 252 ASSERT(has_expression_temp_var()); |
254 return expression_temp_var(); | 253 return expression_temp_var(); |
255 } | 254 } |
256 | 255 |
257 | 256 |
258 void ParsedFunction::EnsureFinallyReturnTemp(bool is_async) { | 257 void ParsedFunction::EnsureFinallyReturnTemp(bool is_async) { |
259 if (!has_finally_return_temp_var()) { | 258 if (!has_finally_return_temp_var()) { |
260 LocalVariable* temp = new(Z) LocalVariable( | 259 LocalVariable* temp = |
261 function_.token_pos(), | 260 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), |
262 function_.token_pos(), | 261 Symbols::FinallyRetVal(), Object::dynamic_type()); |
263 Symbols::FinallyRetVal(), | |
264 Object::dynamic_type()); | |
265 ASSERT(temp != NULL); | 262 ASSERT(temp != NULL); |
266 temp->set_is_final(); | 263 temp->set_is_final(); |
267 if (is_async) { | 264 if (is_async) { |
268 temp->set_is_captured(); | 265 temp->set_is_captured(); |
269 } | 266 } |
270 set_finally_return_temp_var(temp); | 267 set_finally_return_temp_var(temp); |
271 } | 268 } |
272 ASSERT(has_finally_return_temp_var()); | 269 ASSERT(has_finally_return_temp_var()); |
273 } | 270 } |
274 | 271 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 // Parameter i will be at fp[kFirstLocalSlotFromFp - i] and local variable | 318 // Parameter i will be at fp[kFirstLocalSlotFromFp - i] and local variable |
322 // j will be at fp[kFirstLocalSlotFromFp - num_params - j]. | 319 // j will be at fp[kFirstLocalSlotFromFp - num_params - j]. |
323 first_parameter_index_ = kFirstLocalSlotFromFp; | 320 first_parameter_index_ = kFirstLocalSlotFromFp; |
324 first_stack_local_index_ = first_parameter_index_ - num_params; | 321 first_stack_local_index_ = first_parameter_index_ - num_params; |
325 num_copied_params_ = num_params; | 322 num_copied_params_ = num_params; |
326 } | 323 } |
327 | 324 |
328 // Allocate parameters and local variables, either in the local frame or | 325 // Allocate parameters and local variables, either in the local frame or |
329 // in the context(s). | 326 // in the context(s). |
330 bool found_captured_variables = false; | 327 bool found_captured_variables = false; |
331 int next_free_frame_index = | 328 int next_free_frame_index = scope->AllocateVariables( |
332 scope->AllocateVariables(first_parameter_index_, | 329 first_parameter_index_, num_params, first_stack_local_index_, NULL, |
333 num_params, | 330 &found_captured_variables); |
334 first_stack_local_index_, | |
335 NULL, | |
336 &found_captured_variables); | |
337 | 331 |
338 // Frame indices are relative to the frame pointer and are decreasing. | 332 // Frame indices are relative to the frame pointer and are decreasing. |
339 ASSERT(next_free_frame_index <= first_stack_local_index_); | 333 ASSERT(next_free_frame_index <= first_stack_local_index_); |
340 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 334 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
341 } | 335 } |
342 | 336 |
343 | 337 |
344 struct CatchParamDesc { | 338 struct CatchParamDesc { |
345 CatchParamDesc() | 339 CatchParamDesc() |
346 : token_pos(TokenPosition::kNoSource), | 340 : token_pos(TokenPosition::kNoSource), |
347 type(NULL), | 341 type(NULL), |
348 name(NULL), | 342 name(NULL), |
349 var(NULL) { } | 343 var(NULL) {} |
350 TokenPosition token_pos; | 344 TokenPosition token_pos; |
351 const AbstractType* type; | 345 const AbstractType* type; |
352 const String* name; | 346 const String* name; |
353 LocalVariable* var; | 347 LocalVariable* var; |
354 }; | 348 }; |
355 | 349 |
356 | 350 |
357 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 351 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
358 ASSERT(function().IsIrregexpFunction()); | 352 ASSERT(function().IsIrregexpFunction()); |
359 ASSERT(function().NumOptionalParameters() == 0); | 353 ASSERT(function().NumOptionalParameters() == 0); |
360 const intptr_t num_params = function().num_fixed_parameters(); | 354 const intptr_t num_params = function().num_fixed_parameters(); |
361 ASSERT(num_params == RegExpMacroAssembler::kParamCount); | 355 ASSERT(num_params == RegExpMacroAssembler::kParamCount); |
362 // Compute start indices to parameters and locals, and the number of | 356 // Compute start indices to parameters and locals, and the number of |
363 // parameters to copy. | 357 // parameters to copy. |
364 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and | 358 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and |
365 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. | 359 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. |
366 first_parameter_index_ = kParamEndSlotFromFp + num_params; | 360 first_parameter_index_ = kParamEndSlotFromFp + num_params; |
367 first_stack_local_index_ = kFirstLocalSlotFromFp; | 361 first_stack_local_index_ = kFirstLocalSlotFromFp; |
368 num_copied_params_ = 0; | 362 num_copied_params_ = 0; |
369 | 363 |
370 // Frame indices are relative to the frame pointer and are decreasing. | 364 // Frame indices are relative to the frame pointer and are decreasing. |
371 num_stack_locals_ = num_stack_locals; | 365 num_stack_locals_ = num_stack_locals; |
372 } | 366 } |
373 | 367 |
374 | 368 |
375 struct Parser::Block : public ZoneAllocated { | 369 struct Parser::Block : public ZoneAllocated { |
376 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) | 370 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) |
377 : parent(outer_block), scope(local_scope), statements(seq) { | 371 : parent(outer_block), scope(local_scope), statements(seq) { |
378 ASSERT(scope != NULL); | 372 ASSERT(scope != NULL); |
379 ASSERT(statements != NULL); | 373 ASSERT(statements != NULL); |
380 } | 374 } |
381 Block* parent; // Enclosing block, or NULL if outermost. | 375 Block* parent; // Enclosing block, or NULL if outermost. |
382 LocalScope* scope; | 376 LocalScope* scope; |
383 SequenceNode* statements; | 377 SequenceNode* statements; |
384 }; | 378 }; |
385 | 379 |
386 | 380 |
387 // Class which describes an inlined finally block which is used to generate | 381 // Class which describes an inlined finally block which is used to generate |
388 // inlined code for the finally blocks when there is an exit from a try | 382 // inlined code for the finally blocks when there is an exit from a try |
389 // block using 'return', 'break' or 'continue'. | 383 // block using 'return', 'break' or 'continue'. |
390 class Parser::TryStack : public ZoneAllocated { | 384 class Parser::TryStack : public ZoneAllocated { |
391 public: | 385 public: |
392 TryStack(Block* try_block, TryStack* outer_try, intptr_t try_index) | 386 TryStack(Block* try_block, TryStack* outer_try, intptr_t try_index) |
393 : try_block_(try_block), | 387 : try_block_(try_block), |
394 inlined_finally_nodes_(), | 388 inlined_finally_nodes_(), |
395 outer_try_(outer_try), | 389 outer_try_(outer_try), |
396 try_index_(try_index), | 390 try_index_(try_index), |
397 inside_catch_(false), | 391 inside_catch_(false), |
398 inside_finally_(false) { } | 392 inside_finally_(false) {} |
399 | 393 |
400 TryStack* outer_try() const { return outer_try_; } | 394 TryStack* outer_try() const { return outer_try_; } |
401 Block* try_block() const { return try_block_; } | 395 Block* try_block() const { return try_block_; } |
402 intptr_t try_index() const { return try_index_; } | 396 intptr_t try_index() const { return try_index_; } |
403 bool inside_catch() const { return inside_catch_; } | 397 bool inside_catch() const { return inside_catch_; } |
404 void enter_catch() { inside_catch_ = true; } | 398 void enter_catch() { inside_catch_ = true; } |
405 bool inside_finally() const { return inside_finally_; } | 399 bool inside_finally() const { return inside_finally_; } |
406 void enter_finally() { inside_finally_ = true; } | 400 void enter_finally() { inside_finally_ = true; } |
407 void exit_finally() { inside_finally_ = false; } | 401 void exit_finally() { inside_finally_ = false; } |
408 | 402 |
409 void AddNodeForFinallyInlining(AstNode* node); | 403 void AddNodeForFinallyInlining(AstNode* node); |
410 void RemoveJumpToLabel(SourceLabel *label); | 404 void RemoveJumpToLabel(SourceLabel* label); |
411 AstNode* GetNodeToInlineFinally(int index) { | 405 AstNode* GetNodeToInlineFinally(int index) { |
412 if (0 <= index && index < inlined_finally_nodes_.length()) { | 406 if (0 <= index && index < inlined_finally_nodes_.length()) { |
413 return inlined_finally_nodes_[index]; | 407 return inlined_finally_nodes_[index]; |
414 } | 408 } |
415 return NULL; | 409 return NULL; |
416 } | 410 } |
417 | 411 |
418 private: | 412 private: |
419 Block* try_block_; | 413 Block* try_block_; |
420 GrowableArray<AstNode*> inlined_finally_nodes_; | 414 GrowableArray<AstNode*> inlined_finally_nodes_; |
421 TryStack* outer_try_; | 415 TryStack* outer_try_; |
422 const intptr_t try_index_; | 416 const intptr_t try_index_; |
423 bool inside_catch_; // True when parsing a catch clause of this try. | 417 bool inside_catch_; // True when parsing a catch clause of this try. |
424 bool inside_finally_; // True when parsing a finally clause of an inner try | 418 bool inside_finally_; // True when parsing a finally clause of an inner try |
425 // of this try. | 419 // of this try. |
426 | 420 |
427 DISALLOW_COPY_AND_ASSIGN(TryStack); | 421 DISALLOW_COPY_AND_ASSIGN(TryStack); |
428 }; | 422 }; |
429 | 423 |
430 | 424 |
431 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { | 425 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { |
432 inlined_finally_nodes_.Add(node); | 426 inlined_finally_nodes_.Add(node); |
433 } | 427 } |
434 | 428 |
435 | 429 |
436 void Parser::TryStack::RemoveJumpToLabel(SourceLabel *label) { | 430 void Parser::TryStack::RemoveJumpToLabel(SourceLabel* label) { |
437 int i = 0; | 431 int i = 0; |
438 while (i < inlined_finally_nodes_.length()) { | 432 while (i < inlined_finally_nodes_.length()) { |
439 if (inlined_finally_nodes_[i]->IsJumpNode()) { | 433 if (inlined_finally_nodes_[i]->IsJumpNode()) { |
440 JumpNode* jump = inlined_finally_nodes_[i]->AsJumpNode(); | 434 JumpNode* jump = inlined_finally_nodes_[i]->AsJumpNode(); |
441 if (jump->label() == label) { | 435 if (jump->label() == label) { |
442 // Shift remaining entries left and delete last entry. | 436 // Shift remaining entries left and delete last entry. |
443 for (int j = i + 1; j < inlined_finally_nodes_.length(); j++) { | 437 for (int j = i + 1; j < inlined_finally_nodes_.length(); j++) { |
444 inlined_finally_nodes_[j - 1] = inlined_finally_nodes_[j]; | 438 inlined_finally_nodes_[j - 1] = inlined_finally_nodes_[j]; |
445 } | 439 } |
446 inlined_finally_nodes_.RemoveLast(); | 440 inlined_finally_nodes_.RemoveLast(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 tokens_iterator_(zone(), | 488 tokens_iterator_(zone(), |
495 TokenStream::Handle(zone(), script.tokens()), | 489 TokenStream::Handle(zone(), script.tokens()), |
496 token_pos), | 490 token_pos), |
497 token_kind_(Token::kILLEGAL), | 491 token_kind_(Token::kILLEGAL), |
498 current_block_(NULL), | 492 current_block_(NULL), |
499 is_top_level_(false), | 493 is_top_level_(false), |
500 await_is_keyword_(false), | 494 await_is_keyword_(false), |
501 current_member_(NULL), | 495 current_member_(NULL), |
502 allow_function_literals_(true), | 496 allow_function_literals_(true), |
503 parsed_function_(parsed_function), | 497 parsed_function_(parsed_function), |
504 innermost_function_(Function::Handle(zone(), | 498 innermost_function_( |
505 parsed_function->function().raw())), | 499 Function::Handle(zone(), parsed_function->function().raw())), |
506 literal_token_(LiteralToken::Handle(zone())), | 500 literal_token_(LiteralToken::Handle(zone())), |
507 current_class_(Class::Handle(zone(), | 501 current_class_( |
508 parsed_function->function().Owner())), | 502 Class::Handle(zone(), parsed_function->function().Owner())), |
509 library_(Library::Handle(zone(), Class::Handle( | 503 library_(Library::Handle( |
510 zone(), | 504 zone(), |
511 parsed_function->function().origin()).library())), | 505 Class::Handle(zone(), parsed_function->function().origin()) |
| 506 .library())), |
512 try_stack_(NULL), | 507 try_stack_(NULL), |
513 last_used_try_index_(0), | 508 last_used_try_index_(0), |
514 unregister_pending_function_(false), | 509 unregister_pending_function_(false), |
515 async_temp_scope_(NULL), | 510 async_temp_scope_(NULL), |
516 trace_indent_(0), | 511 trace_indent_(0), |
517 recursion_counter_(0) { | 512 recursion_counter_(0) { |
518 ASSERT(tokens_iterator_.IsValid()); | 513 ASSERT(tokens_iterator_.IsValid()); |
519 ASSERT(!current_function().IsNull()); | 514 ASSERT(!current_function().IsNull()); |
520 EnsureExpressionTemp(); | 515 EnsureExpressionTemp(); |
521 } | 516 } |
522 | 517 |
523 | 518 |
524 Parser::~Parser() { | 519 Parser::~Parser() { |
525 if (unregister_pending_function_) { | 520 if (unregister_pending_function_) { |
526 const GrowableObjectArray& pending_functions = | 521 const GrowableObjectArray& pending_functions = |
527 GrowableObjectArray::Handle(T->pending_functions()); | 522 GrowableObjectArray::Handle(T->pending_functions()); |
528 ASSERT(!pending_functions.IsNull()); | 523 ASSERT(!pending_functions.IsNull()); |
529 ASSERT(pending_functions.Length() > 0); | 524 ASSERT(pending_functions.Length() > 0); |
530 ASSERT(pending_functions.At(pending_functions.Length() - 1) == | 525 ASSERT(pending_functions.At(pending_functions.Length() - 1) == |
531 current_function().raw()); | 526 current_function().raw()); |
532 pending_functions.RemoveLast(); | 527 pending_functions.RemoveLast(); |
533 } | 528 } |
534 } | 529 } |
535 | 530 |
536 | 531 |
537 // Each try in this function gets its own try index. | 532 // Each try in this function gets its own try index. |
538 // See definition of RawPcDescriptors::PcDescriptor. | 533 // See definition of RawPcDescriptors::PcDescriptor. |
539 int16_t Parser::AllocateTryIndex() { | 534 int16_t Parser::AllocateTryIndex() { |
540 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { | 535 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { |
541 ReportError("too many nested try statements"); | 536 ReportError("too many nested try statements"); |
542 } | 537 } |
543 return last_used_try_index_++; | 538 return last_used_try_index_++; |
544 } | 539 } |
545 | 540 |
546 | 541 |
547 void Parser::SetScript(const Script& script, TokenPosition token_pos) { | 542 void Parser::SetScript(const Script& script, TokenPosition token_pos) { |
548 script_ = script.raw(); | 543 script_ = script.raw(); |
549 tokens_iterator_.SetStream( | 544 tokens_iterator_.SetStream(TokenStream::Handle(Z, script.tokens()), |
550 TokenStream::Handle(Z, script.tokens()), token_pos); | 545 token_pos); |
551 token_kind_ = Token::kILLEGAL; | 546 token_kind_ = Token::kILLEGAL; |
552 } | 547 } |
553 | 548 |
554 | 549 |
555 bool Parser::SetAllowFunctionLiterals(bool value) { | 550 bool Parser::SetAllowFunctionLiterals(bool value) { |
556 bool current_value = allow_function_literals_; | 551 bool current_value = allow_function_literals_; |
557 allow_function_literals_ = value; | 552 allow_function_literals_ = value; |
558 return current_value; | 553 return current_value; |
559 } | 554 } |
560 | 555 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 }; | 604 }; |
610 | 605 |
611 | 606 |
612 void Parser::ParseCompilationUnit(const Library& library, | 607 void Parser::ParseCompilationUnit(const Library& library, |
613 const Script& script) { | 608 const Script& script) { |
614 Thread* thread = Thread::Current(); | 609 Thread* thread = Thread::Current(); |
615 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 610 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
616 CSTAT_TIMER_SCOPE(thread, parser_timer); | 611 CSTAT_TIMER_SCOPE(thread, parser_timer); |
617 #ifndef PRODUCT | 612 #ifndef PRODUCT |
618 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 613 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
619 TimelineDurationScope tds(thread, | 614 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
620 Timeline::GetCompilerStream(), | |
621 "CompileTopLevel"); | 615 "CompileTopLevel"); |
622 if (tds.enabled()) { | 616 if (tds.enabled()) { |
623 tds.SetNumArguments(1); | 617 tds.SetNumArguments(1); |
624 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); | 618 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); |
625 } | 619 } |
626 #endif | 620 #endif |
627 | 621 |
628 TopLevelParsingScope scope(thread); | 622 TopLevelParsingScope scope(thread); |
629 Parser parser(script, library, TokenPosition::kMinSource); | 623 Parser parser(script, library, TokenPosition::kMinSource); |
630 parser.ParseTopLevel(); | 624 parser.ParseTopLevel(); |
631 } | 625 } |
632 | 626 |
633 | 627 |
634 void Parser::ComputeCurrentToken() { | 628 void Parser::ComputeCurrentToken() { |
635 ASSERT(token_kind_ == Token::kILLEGAL); | 629 ASSERT(token_kind_ == Token::kILLEGAL); |
636 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 630 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
637 if (token_kind_ == Token::kERROR) { | 631 if (token_kind_ == Token::kERROR) { |
638 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 632 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
639 } | 633 } |
640 } | 634 } |
641 | 635 |
642 | 636 |
643 Token::Kind Parser::LookaheadToken(int num_tokens) { | 637 Token::Kind Parser::LookaheadToken(int num_tokens) { |
644 return tokens_iterator_.LookaheadTokenKind(num_tokens); | 638 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
645 } | 639 } |
646 | 640 |
647 | 641 |
648 String* Parser::CurrentLiteral() const { | 642 String* Parser::CurrentLiteral() const { |
649 String& result = | 643 String& result = String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); |
650 String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); | |
651 return &result; | 644 return &result; |
652 } | 645 } |
653 | 646 |
654 | 647 |
655 RawDouble* Parser::CurrentDoubleLiteral() const { | 648 RawDouble* Parser::CurrentDoubleLiteral() const { |
656 literal_token_ ^= tokens_iterator_.CurrentToken(); | 649 literal_token_ ^= tokens_iterator_.CurrentToken(); |
657 ASSERT(literal_token_.kind() == Token::kDOUBLE); | 650 ASSERT(literal_token_.kind() == Token::kDOUBLE); |
658 return Double::RawCast(literal_token_.value()); | 651 return Double::RawCast(literal_token_.value()); |
659 } | 652 } |
660 | 653 |
661 | 654 |
662 RawInteger* Parser::CurrentIntegerLiteral() const { | 655 RawInteger* Parser::CurrentIntegerLiteral() const { |
663 literal_token_ ^= tokens_iterator_.CurrentToken(); | 656 literal_token_ ^= tokens_iterator_.CurrentToken(); |
664 ASSERT(literal_token_.kind() == Token::kINTEGER); | 657 ASSERT(literal_token_.kind() == Token::kINTEGER); |
665 RawInteger* ri = Integer::RawCast(literal_token_.value()); | 658 RawInteger* ri = Integer::RawCast(literal_token_.value()); |
666 return ri; | 659 return ri; |
667 } | 660 } |
668 | 661 |
669 | 662 |
670 struct ParamDesc { | 663 struct ParamDesc { |
671 ParamDesc() | 664 ParamDesc() |
672 : type(NULL), | 665 : type(NULL), |
673 name_pos(TokenPosition::kNoSource), | 666 name_pos(TokenPosition::kNoSource), |
674 name(NULL), | 667 name(NULL), |
675 default_value(NULL), | 668 default_value(NULL), |
676 metadata(NULL), | 669 metadata(NULL), |
677 var(NULL), | 670 var(NULL), |
678 is_final(false), | 671 is_final(false), |
679 is_field_initializer(false), | 672 is_field_initializer(false), |
680 has_explicit_type(false) { } | 673 has_explicit_type(false) {} |
681 const AbstractType* type; | 674 const AbstractType* type; |
682 TokenPosition name_pos; | 675 TokenPosition name_pos; |
683 const String* name; | 676 const String* name; |
684 const Instance* default_value; // NULL if not an optional parameter. | 677 const Instance* default_value; // NULL if not an optional parameter. |
685 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 678 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
686 LocalVariable* var; // Scope variable allocated for this parameter. | 679 LocalVariable* var; // Scope variable allocated for this parameter. |
687 bool is_final; | 680 bool is_final; |
688 bool is_field_initializer; | 681 bool is_field_initializer; |
689 bool has_explicit_type; | 682 bool has_explicit_type; |
690 }; | 683 }; |
691 | 684 |
692 | 685 |
693 struct ParamList { | 686 struct ParamList { |
694 ParamList() { | 687 ParamList() { Clear(); } |
695 Clear(); | |
696 } | |
697 | 688 |
698 void Clear() { | 689 void Clear() { |
699 num_fixed_parameters = 0; | 690 num_fixed_parameters = 0; |
700 num_optional_parameters = 0; | 691 num_optional_parameters = 0; |
701 has_optional_positional_parameters = false; | 692 has_optional_positional_parameters = false; |
702 has_optional_named_parameters = false; | 693 has_optional_named_parameters = false; |
703 has_explicit_default_values = false; | 694 has_explicit_default_values = false; |
704 has_field_initializer = false; | 695 has_field_initializer = false; |
705 implicitly_final = false; | 696 implicitly_final = false; |
706 skipped = false; | 697 skipped = false; |
707 this->parameters = new ZoneGrowableArray<ParamDesc>(); | 698 this->parameters = new ZoneGrowableArray<ParamDesc>(); |
708 } | 699 } |
709 | 700 |
710 void AddFinalParameter(TokenPosition name_pos, | 701 void AddFinalParameter(TokenPosition name_pos, |
711 const String* name, | 702 const String* name, |
712 const AbstractType* type) { | 703 const AbstractType* type) { |
713 this->num_fixed_parameters++; | 704 this->num_fixed_parameters++; |
714 ParamDesc param; | 705 ParamDesc param; |
715 param.name_pos = name_pos; | 706 param.name_pos = name_pos; |
716 param.name = name; | 707 param.name = name; |
717 param.is_final = true; | 708 param.is_final = true; |
718 param.type = type; | 709 param.type = type; |
719 this->parameters->Add(param); | 710 this->parameters->Add(param); |
720 } | 711 } |
721 | 712 |
722 void AddReceiver(const AbstractType* receiver_type, | 713 void AddReceiver(const AbstractType* receiver_type, TokenPosition token_pos) { |
723 TokenPosition token_pos) { | |
724 ASSERT(this->parameters->is_empty()); | 714 ASSERT(this->parameters->is_empty()); |
725 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); | 715 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); |
726 } | 716 } |
727 | 717 |
728 void EraseParameterTypes() { | 718 void EraseParameterTypes() { |
729 const int num_parameters = parameters->length(); | 719 const int num_parameters = parameters->length(); |
730 for (int i = 0; i < num_parameters; i++) { | 720 for (int i = 0; i < num_parameters; i++) { |
731 (*parameters)[i].type = &Object::dynamic_type(); | 721 (*parameters)[i].type = &Object::dynamic_type(); |
732 } | 722 } |
733 } | 723 } |
(...skipping 15 matching lines...) Expand all Loading... |
749 const intptr_t num_params = parameters->length(); | 739 const intptr_t num_params = parameters->length(); |
750 for (int i = 0; i < num_params; i++) { | 740 for (int i = 0; i < num_params; i++) { |
751 ParamDesc& param = (*parameters)[i]; | 741 ParamDesc& param = (*parameters)[i]; |
752 if (param.is_field_initializer) { | 742 if (param.is_field_initializer) { |
753 ASSERT(param.var != NULL); | 743 ASSERT(param.var != NULL); |
754 param.var->set_invisible(true); | 744 param.var->set_invisible(true); |
755 } | 745 } |
756 } | 746 } |
757 } | 747 } |
758 | 748 |
759 void SetImplicitlyFinal() { | 749 void SetImplicitlyFinal() { implicitly_final = true; } |
760 implicitly_final = true; | |
761 } | |
762 | 750 |
763 int num_fixed_parameters; | 751 int num_fixed_parameters; |
764 int num_optional_parameters; | 752 int num_optional_parameters; |
765 bool has_optional_positional_parameters; | 753 bool has_optional_positional_parameters; |
766 bool has_optional_named_parameters; | 754 bool has_optional_named_parameters; |
767 bool has_explicit_default_values; | 755 bool has_explicit_default_values; |
768 bool has_field_initializer; | 756 bool has_field_initializer; |
769 bool implicitly_final; | 757 bool implicitly_final; |
770 bool skipped; | 758 bool skipped; |
771 ZoneGrowableArray<ParamDesc>* parameters; | 759 ZoneGrowableArray<ParamDesc>* parameters; |
772 }; | 760 }; |
773 | 761 |
774 | 762 |
775 struct MemberDesc { | 763 struct MemberDesc { |
776 MemberDesc() { | 764 MemberDesc() { Clear(); } |
777 Clear(); | |
778 } | |
779 | 765 |
780 void Clear() { | 766 void Clear() { |
781 has_abstract = false; | 767 has_abstract = false; |
782 has_external = false; | 768 has_external = false; |
783 has_final = false; | 769 has_final = false; |
784 has_const = false; | 770 has_const = false; |
785 has_static = false; | 771 has_static = false; |
786 has_var = false; | 772 has_var = false; |
787 has_factory = false; | 773 has_factory = false; |
788 has_operator = false; | 774 has_operator = false; |
(...skipping 12 matching lines...) Expand all Loading... |
801 | 787 |
802 bool IsConstructor() const { | 788 bool IsConstructor() const { |
803 return (kind == RawFunction::kConstructor) && !has_static; | 789 return (kind == RawFunction::kConstructor) && !has_static; |
804 } | 790 } |
805 bool IsFactory() const { | 791 bool IsFactory() const { |
806 return (kind == RawFunction::kConstructor) && has_static; | 792 return (kind == RawFunction::kConstructor) && has_static; |
807 } | 793 } |
808 bool IsFactoryOrConstructor() const { | 794 bool IsFactoryOrConstructor() const { |
809 return (kind == RawFunction::kConstructor); | 795 return (kind == RawFunction::kConstructor); |
810 } | 796 } |
811 bool IsGetter() const { | 797 bool IsGetter() const { return kind == RawFunction::kGetterFunction; } |
812 return kind == RawFunction::kGetterFunction; | 798 bool IsSetter() const { return kind == RawFunction::kSetterFunction; } |
813 } | |
814 bool IsSetter() const { | |
815 return kind == RawFunction::kSetterFunction; | |
816 } | |
817 const char* ToCString() const { | 799 const char* ToCString() const { |
818 if (field_ != NULL) { | 800 if (field_ != NULL) { |
819 return "field"; | 801 return "field"; |
820 } else if (IsConstructor()) { | 802 } else if (IsConstructor()) { |
821 return "constructor"; | 803 return "constructor"; |
822 } else if (IsFactory()) { | 804 } else if (IsFactory()) { |
823 return "factory"; | 805 return "factory"; |
824 } else if (IsGetter()) { | 806 } else if (IsGetter()) { |
825 return "getter"; | 807 return "getter"; |
826 } else if (IsSetter()) { | 808 } else if (IsSetter()) { |
827 return "setter"; | 809 return "setter"; |
828 } | 810 } |
829 return "method"; | 811 return "method"; |
830 } | 812 } |
831 String* DictName() const { | 813 String* DictName() const { return (dict_name != NULL) ? dict_name : name; } |
832 return (dict_name != NULL) ? dict_name : name; | |
833 } | |
834 bool has_abstract; | 814 bool has_abstract; |
835 bool has_external; | 815 bool has_external; |
836 bool has_final; | 816 bool has_final; |
837 bool has_const; | 817 bool has_const; |
838 bool has_static; | 818 bool has_static; |
839 bool has_var; | 819 bool has_var; |
840 bool has_factory; | 820 bool has_factory; |
841 bool has_operator; | 821 bool has_operator; |
842 bool has_native; | 822 bool has_native; |
843 TokenPosition metadata_pos; | 823 TokenPosition metadata_pos; |
(...skipping 22 matching lines...) Expand all Loading... |
866 ClassDesc(Zone* zone, | 846 ClassDesc(Zone* zone, |
867 const Class& cls, | 847 const Class& cls, |
868 const String& cls_name, | 848 const String& cls_name, |
869 bool is_interface, | 849 bool is_interface, |
870 TokenPosition token_pos) | 850 TokenPosition token_pos) |
871 : zone_(zone), | 851 : zone_(zone), |
872 clazz_(cls), | 852 clazz_(cls), |
873 class_name_(cls_name), | 853 class_name_(cls_name), |
874 token_pos_(token_pos), | 854 token_pos_(token_pos), |
875 functions_(zone, 4), | 855 functions_(zone, 4), |
876 fields_(zone, 4) { | 856 fields_(zone, 4) {} |
877 } | |
878 | 857 |
879 void AddFunction(const Function& function) { | 858 void AddFunction(const Function& function) { |
880 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); | 859 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); |
881 } | 860 } |
882 | 861 |
883 const GrowableArray<const Function*>& functions() const { | 862 const GrowableArray<const Function*>& functions() const { return functions_; } |
884 return functions_; | |
885 } | |
886 | 863 |
887 void AddField(const Field& field) { | 864 void AddField(const Field& field) { |
888 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); | 865 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); |
889 } | 866 } |
890 | 867 |
891 const GrowableArray<const Field*>& fields() const { | 868 const GrowableArray<const Field*>& fields() const { return fields_; } |
892 return fields_; | |
893 } | |
894 | 869 |
895 const Class& clazz() const { | 870 const Class& clazz() const { return clazz_; } |
896 return clazz_; | |
897 } | |
898 | 871 |
899 const String& class_name() const { | 872 const String& class_name() const { return class_name_; } |
900 return class_name_; | |
901 } | |
902 | 873 |
903 bool has_constructor() const { | 874 bool has_constructor() const { |
904 for (int i = 0; i < functions_.length(); i++) { | 875 for (int i = 0; i < functions_.length(); i++) { |
905 const Function* func = functions_.At(i); | 876 const Function* func = functions_.At(i); |
906 if (func->kind() == RawFunction::kConstructor) { | 877 if (func->kind() == RawFunction::kConstructor) { |
907 return true; | 878 return true; |
908 } | 879 } |
909 } | 880 } |
910 return false; | 881 return false; |
911 } | 882 } |
912 | 883 |
913 TokenPosition token_pos() const { | 884 TokenPosition token_pos() const { return token_pos_; } |
914 return token_pos_; | |
915 } | |
916 | 885 |
917 void AddMember(const MemberDesc& member) { | 886 void AddMember(const MemberDesc& member) { members_.Add(member); } |
918 members_.Add(member); | |
919 } | |
920 | 887 |
921 const GrowableArray<MemberDesc>& members() const { | 888 const GrowableArray<MemberDesc>& members() const { return members_; } |
922 return members_; | |
923 } | |
924 | 889 |
925 MemberDesc* LookupMember(const String& name) const { | 890 MemberDesc* LookupMember(const String& name) const { |
926 for (int i = 0; i < members_.length(); i++) { | 891 for (int i = 0; i < members_.length(); i++) { |
927 if (name.Equals(*members_[i].name)) { | 892 if (name.Equals(*members_[i].name)) { |
928 return &members_[i]; | 893 return &members_[i]; |
929 } | 894 } |
930 } | 895 } |
931 return NULL; | 896 return NULL; |
932 } | 897 } |
933 | 898 |
934 RawArray* MakeFunctionsArray() { | 899 RawArray* MakeFunctionsArray() { |
935 const intptr_t len = functions_.length(); | 900 const intptr_t len = functions_.length(); |
936 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld)); | 901 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld)); |
937 for (intptr_t i = 0; i < len; i++) { | 902 for (intptr_t i = 0; i < len; i++) { |
938 res.SetAt(i, *functions_[i]); | 903 res.SetAt(i, *functions_[i]); |
939 } | 904 } |
940 return res.raw(); | 905 return res.raw(); |
941 } | 906 } |
942 | 907 |
943 private: | 908 private: |
944 Zone* zone_; | 909 Zone* zone_; |
945 const Class& clazz_; | 910 const Class& clazz_; |
946 const String& class_name_; | 911 const String& class_name_; |
947 TokenPosition token_pos_; // Token index of "class" keyword. | 912 TokenPosition token_pos_; // Token index of "class" keyword. |
948 GrowableArray<const Function*> functions_; | 913 GrowableArray<const Function*> functions_; |
949 GrowableArray<const Field*> fields_; | 914 GrowableArray<const Field*> fields_; |
950 GrowableArray<MemberDesc> members_; | 915 GrowableArray<MemberDesc> members_; |
951 }; | 916 }; |
952 | 917 |
953 | 918 |
954 class TopLevel : public ValueObject { | 919 class TopLevel : public ValueObject { |
955 public: | 920 public: |
956 explicit TopLevel(Zone* zone) : | 921 explicit TopLevel(Zone* zone) |
957 zone_(zone), | 922 : zone_(zone), fields_(zone, 4), functions_(zone, 4) {} |
958 fields_(zone, 4), | |
959 functions_(zone, 4) { } | |
960 | 923 |
961 void AddField(const Field& field) { | 924 void AddField(const Field& field) { |
962 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); | 925 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); |
963 } | 926 } |
964 | 927 |
965 void AddFunction(const Function& function) { | 928 void AddFunction(const Function& function) { |
966 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); | 929 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); |
967 } | 930 } |
968 | 931 |
969 const GrowableArray<const Field*>& fields() const { | 932 const GrowableArray<const Field*>& fields() const { return fields_; } |
970 return fields_; | |
971 } | |
972 | 933 |
973 const GrowableArray<const Function*>& functions() const { | 934 const GrowableArray<const Function*>& functions() const { return functions_; } |
974 return functions_; | |
975 } | |
976 | 935 |
977 private: | 936 private: |
978 Zone* zone_; | 937 Zone* zone_; |
979 GrowableArray<const Field*> fields_; | 938 GrowableArray<const Field*> fields_; |
980 GrowableArray<const Function*> functions_; | 939 GrowableArray<const Function*> functions_; |
981 }; | 940 }; |
982 | 941 |
983 | 942 |
984 void Parser::ParseClass(const Class& cls) { | 943 void Parser::ParseClass(const Class& cls) { |
985 Thread* thread = Thread::Current(); | 944 Thread* thread = Thread::Current(); |
986 Zone* zone = thread->zone(); | 945 Zone* zone = thread->zone(); |
987 const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed); | 946 const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed); |
988 #ifndef PRODUCT | 947 #ifndef PRODUCT |
989 TimelineDurationScope tds(thread, | 948 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
990 Timeline::GetCompilerStream(), | |
991 "ParseClass"); | 949 "ParseClass"); |
992 if (tds.enabled()) { | 950 if (tds.enabled()) { |
993 tds.SetNumArguments(1); | 951 tds.SetNumArguments(1); |
994 tds.CopyArgument(0, "class", String::Handle(cls.Name()).ToCString()); | 952 tds.CopyArgument(0, "class", String::Handle(cls.Name()).ToCString()); |
995 } | 953 } |
996 #endif | 954 #endif |
997 if (!cls.is_synthesized_class()) { | 955 if (!cls.is_synthesized_class()) { |
998 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 956 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
999 CSTAT_TIMER_SCOPE(thread, parser_timer); | 957 CSTAT_TIMER_SCOPE(thread, parser_timer); |
1000 const Script& script = Script::Handle(zone, cls.script()); | 958 const Script& script = Script::Handle(zone, cls.script()); |
(...skipping 16 matching lines...) Expand all Loading... |
1017 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 975 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
1018 ASSERT(!func.IsNull()); | 976 ASSERT(!func.IsNull()); |
1019 LongJumpScope jump; | 977 LongJumpScope jump; |
1020 if (setjmp(*jump.Set()) == 0) { | 978 if (setjmp(*jump.Set()) == 0) { |
1021 Thread* thread = Thread::Current(); | 979 Thread* thread = Thread::Current(); |
1022 StackZone stack_zone(thread); | 980 StackZone stack_zone(thread); |
1023 Zone* zone = stack_zone.GetZone(); | 981 Zone* zone = stack_zone.GetZone(); |
1024 const Script& script = Script::Handle(zone, func.script()); | 982 const Script& script = Script::Handle(zone, func.script()); |
1025 const Class& owner = Class::Handle(zone, func.Owner()); | 983 const Class& owner = Class::Handle(zone, func.Owner()); |
1026 ASSERT(!owner.IsNull()); | 984 ASSERT(!owner.IsNull()); |
1027 ParsedFunction* parsed_function = new ParsedFunction( | 985 ParsedFunction* parsed_function = |
1028 thread, Function::ZoneHandle(zone, func.raw())); | 986 new ParsedFunction(thread, Function::ZoneHandle(zone, func.raw())); |
1029 Parser parser(script, parsed_function, func.token_pos()); | 987 Parser parser(script, parsed_function, func.token_pos()); |
1030 parser.SkipFunctionPreamble(); | 988 parser.SkipFunctionPreamble(); |
1031 ParamList params; | 989 ParamList params; |
1032 parser.ParseFormalParameterList(true, true, ¶ms); | 990 parser.ParseFormalParameterList(true, true, ¶ms); |
1033 ParamDesc* param = params.parameters->data(); | 991 ParamDesc* param = params.parameters->data(); |
1034 const int param_cnt = params.num_fixed_parameters + | 992 const int param_cnt = |
1035 params.num_optional_parameters; | 993 params.num_fixed_parameters + params.num_optional_parameters; |
1036 const Array& param_descriptor = | 994 const Array& param_descriptor = |
1037 Array::Handle(Array::New(param_cnt * kParameterEntrySize, Heap::kOld)); | 995 Array::Handle(Array::New(param_cnt * kParameterEntrySize, Heap::kOld)); |
1038 for (int i = 0, j = 0; i < param_cnt; i++, j += kParameterEntrySize) { | 996 for (int i = 0, j = 0; i < param_cnt; i++, j += kParameterEntrySize) { |
1039 param_descriptor.SetAt(j + kParameterIsFinalOffset, | 997 param_descriptor.SetAt(j + kParameterIsFinalOffset, |
1040 param[i].is_final ? Bool::True() : Bool::False()); | 998 param[i].is_final ? Bool::True() : Bool::False()); |
1041 param_descriptor.SetAt(j + kParameterDefaultValueOffset, | 999 param_descriptor.SetAt(j + kParameterDefaultValueOffset, |
1042 (param[i].default_value == NULL) ? Object::null_instance() : | 1000 (param[i].default_value == NULL) |
1043 *(param[i].default_value)); | 1001 ? Object::null_instance() |
| 1002 : *(param[i].default_value)); |
1044 const Object* metadata = param[i].metadata; | 1003 const Object* metadata = param[i].metadata; |
1045 if ((metadata != NULL) && (*metadata).IsError()) { | 1004 if ((metadata != NULL) && (*metadata).IsError()) { |
1046 return metadata->raw(); // Error evaluating the metadata. | 1005 return metadata->raw(); // Error evaluating the metadata. |
1047 } | 1006 } |
1048 param_descriptor.SetAt(j + kParameterMetadataOffset, | 1007 param_descriptor.SetAt(j + kParameterMetadataOffset, |
1049 (param[i].metadata == NULL) ? Object::null_instance() : | 1008 (param[i].metadata == NULL) |
1050 *(param[i].metadata)); | 1009 ? Object::null_instance() |
| 1010 : *(param[i].metadata)); |
1051 } | 1011 } |
1052 return param_descriptor.raw(); | 1012 return param_descriptor.raw(); |
1053 } else { | 1013 } else { |
1054 Thread* thread = Thread::Current(); | 1014 Thread* thread = Thread::Current(); |
1055 Error& error = Error::Handle(); | 1015 Error& error = Error::Handle(); |
1056 error = thread->sticky_error(); | 1016 error = thread->sticky_error(); |
1057 thread->clear_sticky_error(); | 1017 thread->clear_sticky_error(); |
1058 return error.raw(); | 1018 return error.raw(); |
1059 } | 1019 } |
1060 UNREACHABLE(); | 1020 UNREACHABLE(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 | 1056 |
1097 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 1057 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
1098 Thread* thread = parsed_function->thread(); | 1058 Thread* thread = parsed_function->thread(); |
1099 ASSERT(thread == Thread::Current()); | 1059 ASSERT(thread == Thread::Current()); |
1100 Zone* zone = thread->zone(); | 1060 Zone* zone = thread->zone(); |
1101 CSTAT_TIMER_SCOPE(thread, parser_timer); | 1061 CSTAT_TIMER_SCOPE(thread, parser_timer); |
1102 INC_STAT(thread, num_functions_parsed, 1); | 1062 INC_STAT(thread, num_functions_parsed, 1); |
1103 #ifndef PRODUCT | 1063 #ifndef PRODUCT |
1104 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 1064 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
1105 FLAG_profile_vm); | 1065 FLAG_profile_vm); |
1106 TimelineDurationScope tds(thread, | 1066 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
1107 Timeline::GetCompilerStream(), | |
1108 "ParseFunction"); | 1067 "ParseFunction"); |
1109 #endif // !PRODUCT | 1068 #endif // !PRODUCT |
1110 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 1069 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
1111 ASSERT(parsed_function != NULL); | 1070 ASSERT(parsed_function != NULL); |
1112 const Function& func = parsed_function->function(); | 1071 const Function& func = parsed_function->function(); |
1113 const Script& script = Script::Handle(zone, func.script()); | 1072 const Script& script = Script::Handle(zone, func.script()); |
1114 Parser parser(script, parsed_function, func.token_pos()); | 1073 Parser parser(script, parsed_function, func.token_pos()); |
1115 #ifndef PRODUCT | 1074 #ifndef PRODUCT |
1116 if (tds.enabled()) { | 1075 if (tds.enabled()) { |
1117 tds.SetNumArguments(1); | 1076 tds.SetNumArguments(1); |
1118 tds.CopyArgument(0, "function", String::Handle(func.name()).ToCString()); | 1077 tds.CopyArgument(0, "function", String::Handle(func.name()).ToCString()); |
1119 } | 1078 } |
1120 #endif // !PRODUCT | 1079 #endif // !PRODUCT |
1121 SequenceNode* node_sequence = NULL; | 1080 SequenceNode* node_sequence = NULL; |
1122 switch (func.kind()) { | 1081 switch (func.kind()) { |
1123 case RawFunction::kClosureFunction: | 1082 case RawFunction::kClosureFunction: |
1124 if (func.IsImplicitClosureFunction()) { | 1083 if (func.IsImplicitClosureFunction()) { |
1125 node_sequence = parser.ParseImplicitClosure(func); | 1084 node_sequence = parser.ParseImplicitClosure(func); |
1126 break; | 1085 break; |
1127 } | 1086 } |
1128 if (func.IsConstructorClosureFunction()) { | 1087 if (func.IsConstructorClosureFunction()) { |
1129 node_sequence = parser.ParseConstructorClosure(func); | 1088 node_sequence = parser.ParseConstructorClosure(func); |
1130 break; | 1089 break; |
1131 } | 1090 } |
1132 // Fall-through: Handle non-implicit closures. | 1091 // Fall-through: Handle non-implicit closures. |
1133 case RawFunction::kRegularFunction: | 1092 case RawFunction::kRegularFunction: |
1134 case RawFunction::kGetterFunction: | 1093 case RawFunction::kGetterFunction: |
1135 case RawFunction::kSetterFunction: | 1094 case RawFunction::kSetterFunction: |
1136 case RawFunction::kConstructor: | 1095 case RawFunction::kConstructor: |
1137 // The call to a redirecting factory is redirected. | 1096 // The call to a redirecting factory is redirected. |
1138 ASSERT(!func.IsRedirectingFactory()); | 1097 ASSERT(!func.IsRedirectingFactory()); |
1139 if (!func.IsImplicitConstructor()) { | 1098 if (!func.IsImplicitConstructor()) { |
1140 parser.SkipFunctionPreamble(); | 1099 parser.SkipFunctionPreamble(); |
1141 } | 1100 } |
1142 node_sequence = parser.ParseFunc(func, false); | 1101 node_sequence = parser.ParseFunc(func, false); |
1143 break; | 1102 break; |
1144 case RawFunction::kImplicitGetter: | 1103 case RawFunction::kImplicitGetter: |
1145 ASSERT(!func.is_static()); | 1104 ASSERT(!func.is_static()); |
1146 node_sequence = parser.ParseInstanceGetter(func); | 1105 node_sequence = parser.ParseInstanceGetter(func); |
1147 break; | 1106 break; |
1148 case RawFunction::kImplicitSetter: | 1107 case RawFunction::kImplicitSetter: |
1149 ASSERT(!func.is_static()); | 1108 ASSERT(!func.is_static()); |
1150 node_sequence = parser.ParseInstanceSetter(func); | 1109 node_sequence = parser.ParseInstanceSetter(func); |
1151 break; | 1110 break; |
1152 case RawFunction::kImplicitStaticFinalGetter: | 1111 case RawFunction::kImplicitStaticFinalGetter: |
1153 node_sequence = parser.ParseStaticFinalGetter(func); | 1112 node_sequence = parser.ParseStaticFinalGetter(func); |
1154 INC_STAT(thread, num_implicit_final_getters, 1); | 1113 INC_STAT(thread, num_implicit_final_getters, 1); |
1155 break; | 1114 break; |
1156 case RawFunction::kMethodExtractor: | 1115 case RawFunction::kMethodExtractor: |
1157 node_sequence = parser.ParseMethodExtractor(func); | 1116 node_sequence = parser.ParseMethodExtractor(func); |
1158 INC_STAT(thread, num_method_extractors, 1); | 1117 INC_STAT(thread, num_method_extractors, 1); |
1159 break; | 1118 break; |
1160 case RawFunction::kNoSuchMethodDispatcher: | 1119 case RawFunction::kNoSuchMethodDispatcher: |
1161 node_sequence = | 1120 node_sequence = parser.ParseNoSuchMethodDispatcher(func); |
1162 parser.ParseNoSuchMethodDispatcher(func); | |
1163 break; | 1121 break; |
1164 case RawFunction::kInvokeFieldDispatcher: | 1122 case RawFunction::kInvokeFieldDispatcher: |
1165 node_sequence = | 1123 node_sequence = parser.ParseInvokeFieldDispatcher(func); |
1166 parser.ParseInvokeFieldDispatcher(func); | |
1167 break; | 1124 break; |
1168 case RawFunction::kIrregexpFunction: | 1125 case RawFunction::kIrregexpFunction: |
1169 UNREACHABLE(); // Irregexp functions have their own parser. | 1126 UNREACHABLE(); // Irregexp functions have their own parser. |
1170 default: | 1127 default: |
1171 UNREACHABLE(); | 1128 UNREACHABLE(); |
1172 } | 1129 } |
1173 | 1130 |
1174 if (parsed_function->has_expression_temp_var()) { | 1131 if (parsed_function->has_expression_temp_var()) { |
1175 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 1132 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
1176 } | 1133 } |
1177 node_sequence->scope()->AddVariable( | 1134 node_sequence->scope()->AddVariable(parsed_function->current_context_var()); |
1178 parsed_function->current_context_var()); | |
1179 if (parsed_function->has_finally_return_temp_var()) { | 1135 if (parsed_function->has_finally_return_temp_var()) { |
1180 node_sequence->scope()->AddVariable( | 1136 node_sequence->scope()->AddVariable( |
1181 parsed_function->finally_return_temp_var()); | 1137 parsed_function->finally_return_temp_var()); |
1182 } | 1138 } |
1183 parsed_function->SetNodeSequence(node_sequence); | 1139 parsed_function->SetNodeSequence(node_sequence); |
1184 | 1140 |
1185 // The instantiator may be required at run time for generic type checks or | 1141 // The instantiator may be required at run time for generic type checks or |
1186 // allocation of generic types. | 1142 // allocation of generic types. |
1187 if (parser.IsInstantiatorRequired()) { | 1143 if (parser.IsInstantiatorRequired()) { |
1188 // In the case of a local function, only set the instantiator if the | 1144 // In the case of a local function, only set the instantiator if the |
(...skipping 20 matching lines...) Expand all Loading... |
1209 Thread* thread = Thread::Current(); | 1165 Thread* thread = Thread::Current(); |
1210 StackZone stack_zone(thread); | 1166 StackZone stack_zone(thread); |
1211 Zone* zone = stack_zone.GetZone(); | 1167 Zone* zone = stack_zone.GetZone(); |
1212 const Class& owner_class = Class::Handle(zone, meta_data.Owner()); | 1168 const Class& owner_class = Class::Handle(zone, meta_data.Owner()); |
1213 const Script& script = Script::Handle(zone, meta_data.Script()); | 1169 const Script& script = Script::Handle(zone, meta_data.Script()); |
1214 const TokenPosition token_pos = meta_data.token_pos(); | 1170 const TokenPosition token_pos = meta_data.token_pos(); |
1215 // Parsing metadata can involve following paths in the parser that are | 1171 // Parsing metadata can involve following paths in the parser that are |
1216 // normally used for expressions and assume current_function is non-null, | 1172 // normally used for expressions and assume current_function is non-null, |
1217 // so we create a fake function to use as the current_function rather than | 1173 // so we create a fake function to use as the current_function rather than |
1218 // scattering special cases throughout the parser. | 1174 // scattering special cases throughout the parser. |
1219 const Function& fake_function = Function::ZoneHandle(zone, Function::New( | 1175 const Function& fake_function = Function::ZoneHandle( |
1220 Symbols::At(), | 1176 zone, |
1221 RawFunction::kRegularFunction, | 1177 Function::New(Symbols::At(), RawFunction::kRegularFunction, |
1222 true, // is_static | 1178 true, // is_static |
1223 false, // is_const | 1179 false, // is_const |
1224 false, // is_abstract | 1180 false, // is_abstract |
1225 false, // is_external | 1181 false, // is_external |
1226 false, // is_native | 1182 false, // is_native |
1227 Object::Handle(zone, meta_data.RawOwner()), | 1183 Object::Handle(zone, meta_data.RawOwner()), token_pos)); |
1228 token_pos)); | |
1229 fake_function.set_is_debuggable(false); | 1184 fake_function.set_is_debuggable(false); |
1230 ParsedFunction* parsed_function = | 1185 ParsedFunction* parsed_function = new ParsedFunction(thread, fake_function); |
1231 new ParsedFunction(thread, fake_function); | |
1232 Parser parser(script, parsed_function, token_pos); | 1186 Parser parser(script, parsed_function, token_pos); |
1233 parser.set_current_class(owner_class); | 1187 parser.set_current_class(owner_class); |
1234 parser.OpenFunctionBlock(fake_function); | 1188 parser.OpenFunctionBlock(fake_function); |
1235 | 1189 |
1236 RawObject* metadata = parser.EvaluateMetadata(); | 1190 RawObject* metadata = parser.EvaluateMetadata(); |
1237 return metadata; | 1191 return metadata; |
1238 } else { | 1192 } else { |
1239 Thread* thread = Thread::Current(); | 1193 Thread* thread = Thread::Current(); |
1240 StackZone stack_zone(thread); | 1194 StackZone stack_zone(thread); |
1241 Zone* zone = stack_zone.GetZone(); | 1195 Zone* zone = stack_zone.GetZone(); |
(...skipping 21 matching lines...) Expand all Loading... |
1263 Object& obj = | 1217 Object& obj = |
1264 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); | 1218 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); |
1265 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 1219 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
1266 if (LibraryPrefix::Cast(obj).is_deferred_load()) { | 1220 if (LibraryPrefix::Cast(obj).is_deferred_load()) { |
1267 ReportError("Metadata must be compile-time constant"); | 1221 ReportError("Metadata must be compile-time constant"); |
1268 } | 1222 } |
1269 } | 1223 } |
1270 AstNode* expr = NULL; | 1224 AstNode* expr = NULL; |
1271 if ((LookaheadToken(1) == Token::kLPAREN) || | 1225 if ((LookaheadToken(1) == Token::kLPAREN) || |
1272 ((LookaheadToken(1) == Token::kPERIOD) && | 1226 ((LookaheadToken(1) == Token::kPERIOD) && |
1273 (LookaheadToken(3) == Token::kLPAREN)) || | 1227 (LookaheadToken(3) == Token::kLPAREN)) || |
1274 ((LookaheadToken(1) == Token::kPERIOD) && | 1228 ((LookaheadToken(1) == Token::kPERIOD) && |
1275 (LookaheadToken(3) == Token::kPERIOD) && | 1229 (LookaheadToken(3) == Token::kPERIOD) && |
1276 (LookaheadToken(5) == Token::kLPAREN))) { | 1230 (LookaheadToken(5) == Token::kLPAREN))) { |
1277 expr = ParseNewOperator(Token::kCONST); | 1231 expr = ParseNewOperator(Token::kCONST); |
1278 } else { | 1232 } else { |
1279 // Can be x, C.x, or L.C.x. | 1233 // Can be x, C.x, or L.C.x. |
1280 expr = ParsePrimary(); // Consumes x, C or L.C. | 1234 expr = ParsePrimary(); // Consumes x, C or L.C. |
1281 Class& cls = Class::Handle(Z); | 1235 Class& cls = Class::Handle(Z); |
1282 if (expr->IsPrimaryNode()) { | 1236 if (expr->IsPrimaryNode()) { |
1283 PrimaryNode* primary_node = expr->AsPrimaryNode(); | 1237 PrimaryNode* primary_node = expr->AsPrimaryNode(); |
1284 if (primary_node->primary().IsClass()) { | 1238 if (primary_node->primary().IsClass()) { |
1285 // If the primary node referred to a class we are loading a | 1239 // If the primary node referred to a class we are loading a |
1286 // qualified static field. | 1240 // qualified static field. |
1287 cls ^= primary_node->primary().raw(); | 1241 cls ^= primary_node->primary().raw(); |
1288 } else { | 1242 } else { |
1289 ReportError(expr_pos, | 1243 ReportError(expr_pos, |
1290 "Metadata expressions must refer to a const field " | 1244 "Metadata expressions must refer to a const field " |
1291 "or constructor"); | 1245 "or constructor"); |
1292 } | 1246 } |
1293 } | 1247 } |
1294 if (CurrentToken() == Token::kPERIOD) { | 1248 if (CurrentToken() == Token::kPERIOD) { |
1295 // C.x or L.C.X. | 1249 // C.x or L.C.X. |
1296 if (cls.IsNull()) { | 1250 if (cls.IsNull()) { |
1297 ReportError(expr_pos, | 1251 ReportError(expr_pos, |
1298 "Metadata expressions must refer to a const field " | 1252 "Metadata expressions must refer to a const field " |
1299 "or constructor"); | 1253 "or constructor"); |
1300 } | 1254 } |
1301 ConsumeToken(); | 1255 ConsumeToken(); |
1302 const TokenPosition ident_pos = TokenPos(); | 1256 const TokenPosition ident_pos = TokenPos(); |
1303 String* ident = ExpectIdentifier("identifier expected"); | 1257 String* ident = ExpectIdentifier("identifier expected"); |
1304 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); | 1258 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); |
1305 if (field.IsNull()) { | 1259 if (field.IsNull()) { |
1306 ReportError(ident_pos, | 1260 ReportError(ident_pos, "Class '%s' has no field '%s'", |
1307 "Class '%s' has no field '%s'", | 1261 cls.ToCString(), ident->ToCString()); |
1308 cls.ToCString(), | |
1309 ident->ToCString()); | |
1310 } | 1262 } |
1311 if (!field.is_const()) { | 1263 if (!field.is_const()) { |
1312 ReportError(ident_pos, | 1264 ReportError(ident_pos, "Field '%s' of class '%s' is not const", |
1313 "Field '%s' of class '%s' is not const", | 1265 ident->ToCString(), cls.ToCString()); |
1314 ident->ToCString(), | |
1315 cls.ToCString()); | |
1316 } | 1266 } |
1317 expr = GenerateStaticFieldLookup(field, ident_pos); | 1267 expr = GenerateStaticFieldLookup(field, ident_pos); |
1318 } | 1268 } |
1319 } | 1269 } |
1320 if (expr->EvalConstExpr() == NULL) { | 1270 if (expr->EvalConstExpr() == NULL) { |
1321 ReportError(expr_pos, "expression must be a compile-time constant"); | 1271 ReportError(expr_pos, "expression must be a compile-time constant"); |
1322 } | 1272 } |
1323 const Instance& val = EvaluateConstExpr(expr_pos, expr); | 1273 const Instance& val = EvaluateConstExpr(expr_pos, expr); |
1324 meta_values.Add(val, Heap::kOld); | 1274 meta_values.Add(val, Heap::kOld); |
1325 } | 1275 } |
1326 return Array::MakeArray(meta_values); | 1276 return Array::MakeArray(meta_values); |
1327 } | 1277 } |
1328 | 1278 |
1329 | 1279 |
1330 SequenceNode* Parser::ParseStaticInitializer() { | 1280 SequenceNode* Parser::ParseStaticInitializer() { |
1331 ExpectIdentifier("field name expected"); | 1281 ExpectIdentifier("field name expected"); |
1332 CheckToken(Token::kASSIGN, "field initialier expected"); | 1282 CheckToken(Token::kASSIGN, "field initialier expected"); |
1333 ConsumeToken(); | 1283 ConsumeToken(); |
1334 OpenFunctionBlock(parsed_function()->function()); | 1284 OpenFunctionBlock(parsed_function()->function()); |
1335 TokenPosition expr_pos = TokenPos(); | 1285 TokenPosition expr_pos = TokenPos(); |
1336 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1286 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
1337 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); | 1287 ReturnNode* ret = new (Z) ReturnNode(expr_pos, expr); |
1338 current_block_->statements->Add(ret); | 1288 current_block_->statements->Add(ret); |
1339 return CloseBlock(); | 1289 return CloseBlock(); |
1340 } | 1290 } |
1341 | 1291 |
1342 | 1292 |
1343 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1293 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
1344 ASSERT(field.is_static()); | 1294 ASSERT(field.is_static()); |
1345 Thread* thread = Thread::Current(); | 1295 Thread* thread = Thread::Current(); |
1346 // TODO(koda): Should there be a StackZone here? | 1296 // TODO(koda): Should there be a StackZone here? |
1347 Zone* zone = thread->zone(); | 1297 Zone* zone = thread->zone(); |
1348 #ifndef PRODUCT | 1298 #ifndef PRODUCT |
1349 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 1299 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
1350 FLAG_profile_vm); | 1300 FLAG_profile_vm); |
1351 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 1301 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
1352 "ParseStaticFieldInitializer"); | 1302 "ParseStaticFieldInitializer"); |
1353 #endif // !PRODUCT | 1303 #endif // !PRODUCT |
1354 | 1304 |
1355 const String& field_name = String::Handle(zone, field.name()); | 1305 const String& field_name = String::Handle(zone, field.name()); |
1356 String& init_name = String::Handle(zone, | 1306 String& init_name = String::Handle( |
1357 Symbols::FromConcat(thread, Symbols::InitPrefix(), field_name)); | 1307 zone, Symbols::FromConcat(thread, Symbols::InitPrefix(), field_name)); |
1358 | 1308 |
1359 const Script& script = Script::Handle(zone, field.Script()); | 1309 const Script& script = Script::Handle(zone, field.Script()); |
1360 Object& initializer_owner = Object::Handle(field.Owner()); | 1310 Object& initializer_owner = Object::Handle(field.Owner()); |
1361 initializer_owner = | 1311 initializer_owner = PatchClass::New(Class::Handle(field.Owner()), script); |
1362 PatchClass::New(Class::Handle(field.Owner()), script); | |
1363 | 1312 |
1364 const Function& initializer = Function::ZoneHandle(zone, | 1313 const Function& initializer = Function::ZoneHandle( |
1365 Function::New(init_name, | 1314 zone, Function::New(init_name, RawFunction::kImplicitStaticFinalGetter, |
1366 RawFunction::kImplicitStaticFinalGetter, | 1315 true, // static |
1367 true, // static | 1316 false, // !const |
1368 false, // !const | 1317 false, // !abstract |
1369 false, // !abstract | 1318 false, // !external |
1370 false, // !external | 1319 false, // !native |
1371 false, // !native | 1320 initializer_owner, field.token_pos())); |
1372 initializer_owner, | |
1373 field.token_pos())); | |
1374 initializer.set_result_type(AbstractType::Handle(zone, field.type())); | 1321 initializer.set_result_type(AbstractType::Handle(zone, field.type())); |
1375 // Static initializer functions are hidden from the user. | 1322 // Static initializer functions are hidden from the user. |
1376 // Since they are only executed once, we avoid inlining them. | 1323 // Since they are only executed once, we avoid inlining them. |
1377 // After the field is initialized, the compiler can eliminate | 1324 // After the field is initialized, the compiler can eliminate |
1378 // the call to the static initializer. | 1325 // the call to the static initializer. |
1379 initializer.set_is_reflectable(false); | 1326 initializer.set_is_reflectable(false); |
1380 initializer.set_is_debuggable(false); | 1327 initializer.set_is_debuggable(false); |
1381 initializer.set_is_inlinable(false); | 1328 initializer.set_is_inlinable(false); |
1382 | 1329 |
1383 ParsedFunction* parsed_function = new ParsedFunction(thread, initializer); | 1330 ParsedFunction* parsed_function = new ParsedFunction(thread, initializer); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 if (expr->EvalConstExpr() == NULL) { | 1380 if (expr->EvalConstExpr() == NULL) { |
1434 ReportError(expr_pos, "initializer is not a valid compile-time constant"); | 1381 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
1435 } | 1382 } |
1436 ReturnNode* return_node = new ReturnNode(ident_pos, expr); | 1383 ReturnNode* return_node = new ReturnNode(ident_pos, expr); |
1437 current_block_->statements->Add(return_node); | 1384 current_block_->statements->Add(return_node); |
1438 } else { | 1385 } else { |
1439 // This getter may be called each time the static field is accessed. | 1386 // This getter may be called each time the static field is accessed. |
1440 // Call runtime support to parse and evaluate the initializer expression. | 1387 // Call runtime support to parse and evaluate the initializer expression. |
1441 // The runtime function will detect circular dependencies in expressions | 1388 // The runtime function will detect circular dependencies in expressions |
1442 // and handle errors while evaluating the expression. | 1389 // and handle errors while evaluating the expression. |
1443 current_block_->statements->Add( | 1390 current_block_->statements->Add(new (Z) |
1444 new (Z) InitStaticFieldNode(ident_pos, field)); | 1391 InitStaticFieldNode(ident_pos, field)); |
1445 ReturnNode* return_node = | 1392 ReturnNode* return_node = |
1446 new ReturnNode(ident_pos, | 1393 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); |
1447 new LoadStaticFieldNode(ident_pos, field)); | |
1448 current_block_->statements->Add(return_node); | 1394 current_block_->statements->Add(return_node); |
1449 } | 1395 } |
1450 return CloseBlock(); | 1396 return CloseBlock(); |
1451 } | 1397 } |
1452 | 1398 |
1453 | 1399 |
1454 // Create AstNodes for an implicit instance getter method: | 1400 // Create AstNodes for an implicit instance getter method: |
1455 // LoadLocalNode 0 ('this'); | 1401 // LoadLocalNode 0 ('this'); |
1456 // LoadInstanceFieldNode (field_name); | 1402 // LoadInstanceFieldNode (field_name); |
1457 // ReturnNode (field's value); | 1403 // ReturnNode (field's value); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 const TokenPosition ident_pos = func.token_pos(); | 1447 const TokenPosition ident_pos = func.token_pos(); |
1502 const String& field_name = *CurrentLiteral(); | 1448 const String& field_name = *CurrentLiteral(); |
1503 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); | 1449 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); |
1504 const Field& field = | 1450 const Field& field = |
1505 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1451 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
1506 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | 1452 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
1507 | 1453 |
1508 ParamList params; | 1454 ParamList params; |
1509 ASSERT(current_class().raw() == func.Owner()); | 1455 ASSERT(current_class().raw() == func.Owner()); |
1510 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1456 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1511 params.AddFinalParameter(ident_pos, | 1457 params.AddFinalParameter(ident_pos, &Symbols::Value(), &field_type); |
1512 &Symbols::Value(), | |
1513 &field_type); | |
1514 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. | 1458 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. |
1515 ASSERT(!func.HasOptionalParameters()); | 1459 ASSERT(!func.HasOptionalParameters()); |
1516 ASSERT(AbstractType::Handle(Z, func.result_type()).IsVoidType()); | 1460 ASSERT(AbstractType::Handle(Z, func.result_type()).IsVoidType()); |
1517 | 1461 |
1518 // Build local scope for function and populate with the formal parameters. | 1462 // Build local scope for function and populate with the formal parameters. |
1519 OpenFunctionBlock(func); | 1463 OpenFunctionBlock(func); |
1520 AddFormalParamsToScope(¶ms, current_block_->scope); | 1464 AddFormalParamsToScope(¶ms, current_block_->scope); |
1521 | 1465 |
1522 LoadLocalNode* receiver = | 1466 LoadLocalNode* receiver = |
1523 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); | 1467 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); |
(...skipping 15 matching lines...) Expand all Loading... |
1539 const TokenPosition token_pos = func.token_pos(); | 1483 const TokenPosition token_pos = func.token_pos(); |
1540 | 1484 |
1541 Function& constructor = Function::ZoneHandle(Z); | 1485 Function& constructor = Function::ZoneHandle(Z); |
1542 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1486 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
1543 ParseConstructorClosurization(&constructor, &type_args); | 1487 ParseConstructorClosurization(&constructor, &type_args); |
1544 ASSERT(!constructor.IsNull()); | 1488 ASSERT(!constructor.IsNull()); |
1545 | 1489 |
1546 ParamList params; | 1490 ParamList params; |
1547 // The first parameter of the closure function is the | 1491 // The first parameter of the closure function is the |
1548 // implicit closure argument. | 1492 // implicit closure argument. |
1549 params.AddFinalParameter(token_pos, | 1493 params.AddFinalParameter(token_pos, &Symbols::ClosureParameter(), |
1550 &Symbols::ClosureParameter(), | |
1551 &Object::dynamic_type()); | 1494 &Object::dynamic_type()); |
1552 bool params_ok = ParseFormalParameters(constructor, ¶ms); | 1495 bool params_ok = ParseFormalParameters(constructor, ¶ms); |
1553 USE(params_ok); | 1496 USE(params_ok); |
1554 ASSERT(params_ok); | 1497 ASSERT(params_ok); |
1555 // Per language spec, the type of the closure parameters is dynamic. | 1498 // Per language spec, the type of the closure parameters is dynamic. |
1556 // Replace the types parsed from the constructor. | 1499 // Replace the types parsed from the constructor. |
1557 params.EraseParameterTypes(); | 1500 params.EraseParameterTypes(); |
1558 | 1501 |
1559 SetupDefaultsForOptionalParams(params); | 1502 SetupDefaultsForOptionalParams(params); |
1560 ASSERT(func.num_fixed_parameters() == params.num_fixed_parameters); | 1503 ASSERT(func.num_fixed_parameters() == params.num_fixed_parameters); |
(...skipping 27 matching lines...) Expand all Loading... |
1588 } | 1531 } |
1589 | 1532 |
1590 | 1533 |
1591 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { | 1534 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { |
1592 TRACE_PARSER("ParseImplicitClosure"); | 1535 TRACE_PARSER("ParseImplicitClosure"); |
1593 TokenPosition token_pos = func.token_pos(); | 1536 TokenPosition token_pos = func.token_pos(); |
1594 | 1537 |
1595 OpenFunctionBlock(func); | 1538 OpenFunctionBlock(func); |
1596 | 1539 |
1597 ParamList params; | 1540 ParamList params; |
1598 params.AddFinalParameter( | 1541 params.AddFinalParameter(token_pos, &Symbols::ClosureParameter(), |
1599 token_pos, | 1542 &Object::dynamic_type()); |
1600 &Symbols::ClosureParameter(), | |
1601 &Object::dynamic_type()); | |
1602 | 1543 |
1603 const Function& parent = Function::Handle(func.parent_function()); | 1544 const Function& parent = Function::Handle(func.parent_function()); |
1604 if (parent.IsImplicitSetterFunction()) { | 1545 if (parent.IsImplicitSetterFunction()) { |
1605 const TokenPosition ident_pos = func.token_pos(); | 1546 const TokenPosition ident_pos = func.token_pos(); |
1606 ASSERT(IsIdentifier()); | 1547 ASSERT(IsIdentifier()); |
1607 params.AddFinalParameter(ident_pos, | 1548 params.AddFinalParameter(ident_pos, &Symbols::Value(), |
1608 &Symbols::Value(), | |
1609 &Object::dynamic_type()); | 1549 &Object::dynamic_type()); |
1610 ASSERT(func.num_fixed_parameters() == 2); // closure, value. | 1550 ASSERT(func.num_fixed_parameters() == 2); // closure, value. |
1611 } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) { | 1551 } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) { |
1612 // NOTE: For the `kernel -> flowgraph` we don't use the parser. | 1552 // NOTE: For the `kernel -> flowgraph` we don't use the parser. |
1613 if (parent.kernel_function() == NULL) { | 1553 if (parent.kernel_function() == NULL) { |
1614 const bool allow_explicit_default_values = true; | 1554 const bool allow_explicit_default_values = true; |
1615 SkipFunctionPreamble(); | 1555 SkipFunctionPreamble(); |
1616 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 1556 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
1617 SetupDefaultsForOptionalParams(params); | 1557 SetupDefaultsForOptionalParams(params); |
1618 } | 1558 } |
(...skipping 22 matching lines...) Expand all Loading... |
1641 arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index))); | 1581 arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index))); |
1642 } | 1582 } |
1643 func_args->set_names(arg_names); | 1583 func_args->set_names(arg_names); |
1644 } | 1584 } |
1645 | 1585 |
1646 const String& func_name = String::ZoneHandle(parent.name()); | 1586 const String& func_name = String::ZoneHandle(parent.name()); |
1647 const Class& owner = Class::Handle(parent.Owner()); | 1587 const Class& owner = Class::Handle(parent.Owner()); |
1648 Function& target = Function::ZoneHandle(owner.LookupFunction(func_name)); | 1588 Function& target = Function::ZoneHandle(owner.LookupFunction(func_name)); |
1649 if (target.raw() != parent.raw()) { | 1589 if (target.raw() != parent.raw()) { |
1650 ASSERT(Isolate::Current()->HasAttemptedReload()); | 1590 ASSERT(Isolate::Current()->HasAttemptedReload()); |
1651 if (target.IsNull() || | 1591 if (target.IsNull() || (target.is_static() != parent.is_static()) || |
1652 (target.is_static() != parent.is_static()) || | |
1653 (target.kind() != parent.kind())) { | 1592 (target.kind() != parent.kind())) { |
1654 target = Function::null(); | 1593 target = Function::null(); |
1655 } | 1594 } |
1656 } | 1595 } |
1657 | 1596 |
1658 AstNode* call = NULL; | 1597 AstNode* call = NULL; |
1659 // Check the target still exists and has compatible parameters. If not, | 1598 // Check the target still exists and has compatible parameters. If not, |
1660 // throw NSME/call nSM instead of forwarding the call. Note we compare the | 1599 // throw NSME/call nSM instead of forwarding the call. Note we compare the |
1661 // parent not func because func has an extra parameter for the closure | 1600 // parent not func because func has an extra parameter for the closure |
1662 // receiver. | 1601 // receiver. |
1663 if (!target.IsNull() && | 1602 if (!target.IsNull() && |
1664 (parent.num_fixed_parameters() == target.num_fixed_parameters())) { | 1603 (parent.num_fixed_parameters() == target.num_fixed_parameters())) { |
1665 call = new StaticCallNode(token_pos, target, func_args); | 1604 call = new StaticCallNode(token_pos, target, func_args); |
1666 } else if (!parent.is_static()) { | 1605 } else if (!parent.is_static()) { |
1667 ASSERT(Isolate::Current()->HasAttemptedReload()); | 1606 ASSERT(Isolate::Current()->HasAttemptedReload()); |
1668 // If a subsequent reload reintroduces the target in the middle of the | 1607 // If a subsequent reload reintroduces the target in the middle of the |
1669 // Invocation object being constructed, we won't be able to successfully | 1608 // Invocation object being constructed, we won't be able to successfully |
1670 // deopt because the generated AST will change. | 1609 // deopt because the generated AST will change. |
1671 func.SetIsOptimizable(false); | 1610 func.SetIsOptimizable(false); |
1672 | 1611 |
1673 ArgumentListNode* arguments = BuildNoSuchMethodArguments( | 1612 ArgumentListNode* arguments = BuildNoSuchMethodArguments( |
1674 token_pos, func_name, *func_args, NULL, false); | 1613 token_pos, func_name, *func_args, NULL, false); |
1675 const intptr_t kNumArguments = 2; // Receiver, InvocationMirror. | 1614 const intptr_t kNumArguments = 2; // Receiver, InvocationMirror. |
1676 ArgumentsDescriptor args_desc( | 1615 ArgumentsDescriptor args_desc( |
1677 Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments))); | 1616 Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments))); |
1678 Function& no_such_method = Function::ZoneHandle(Z, | 1617 Function& no_such_method = |
1679 Resolver::ResolveDynamicForReceiverClass(owner, | 1618 Function::ZoneHandle(Z, Resolver::ResolveDynamicForReceiverClass( |
1680 Symbols::NoSuchMethod(), | 1619 owner, Symbols::NoSuchMethod(), args_desc)); |
1681 args_desc)); | |
1682 if (no_such_method.IsNull()) { | 1620 if (no_such_method.IsNull()) { |
1683 // If noSuchMethod(i) is not found, call Object:noSuchMethod. | 1621 // If noSuchMethod(i) is not found, call Object:noSuchMethod. |
1684 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( | 1622 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( |
1685 Class::Handle(Z, I->object_store()->object_class()), | 1623 Class::Handle(Z, I->object_store()->object_class()), |
1686 Symbols::NoSuchMethod(), | 1624 Symbols::NoSuchMethod(), args_desc); |
1687 args_desc); | |
1688 } | 1625 } |
1689 call = new StaticCallNode(token_pos, no_such_method, arguments); | 1626 call = new StaticCallNode(token_pos, no_such_method, arguments); |
1690 } else { | 1627 } else { |
1691 ASSERT(Isolate::Current()->HasAttemptedReload()); | 1628 ASSERT(Isolate::Current()->HasAttemptedReload()); |
1692 // If a subsequent reload reintroduces the target in the middle of the | 1629 // If a subsequent reload reintroduces the target in the middle of the |
1693 // arguments array being constructed, we won't be able to successfully | 1630 // arguments array being constructed, we won't be able to successfully |
1694 // deopt because the generated AST will change. | 1631 // deopt because the generated AST will change. |
1695 func.SetIsOptimizable(false); | 1632 func.SetIsOptimizable(false); |
1696 | 1633 |
1697 InvocationMirror::Type im_type; | 1634 InvocationMirror::Type im_type; |
1698 if (parent.IsImplicitGetterFunction()) { | 1635 if (parent.IsImplicitGetterFunction()) { |
1699 im_type = InvocationMirror::kGetter; | 1636 im_type = InvocationMirror::kGetter; |
1700 } else if (parent.IsImplicitSetterFunction()) { | 1637 } else if (parent.IsImplicitSetterFunction()) { |
1701 im_type = InvocationMirror::kSetter; | 1638 im_type = InvocationMirror::kSetter; |
1702 } else { | 1639 } else { |
1703 im_type = InvocationMirror::kMethod; | 1640 im_type = InvocationMirror::kMethod; |
1704 } | 1641 } |
1705 call = ThrowNoSuchMethodError(TokenPos(), | 1642 call = ThrowNoSuchMethodError(TokenPos(), owner, func_name, func_args, |
1706 owner, | 1643 InvocationMirror::kStatic, im_type, |
1707 func_name, | |
1708 func_args, | |
1709 InvocationMirror::kStatic, | |
1710 im_type, | |
1711 NULL); // No existing function. | 1644 NULL); // No existing function. |
1712 } | 1645 } |
1713 | 1646 |
1714 ASSERT(call != NULL); | 1647 ASSERT(call != NULL); |
1715 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1648 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1716 current_block_->statements->Add(return_node); | 1649 current_block_->statements->Add(return_node); |
1717 return CloseBlock(); | 1650 return CloseBlock(); |
1718 } | 1651 } |
1719 | 1652 |
1720 | 1653 |
(...skipping 11 matching lines...) Expand all Loading... |
1732 | 1665 |
1733 // Build local scope for function and populate with the formal parameters. | 1666 // Build local scope for function and populate with the formal parameters. |
1734 OpenFunctionBlock(func); | 1667 OpenFunctionBlock(func); |
1735 AddFormalParamsToScope(¶ms, current_block_->scope); | 1668 AddFormalParamsToScope(¶ms, current_block_->scope); |
1736 | 1669 |
1737 // Receiver is local 0. | 1670 // Receiver is local 0. |
1738 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1671 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1739 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1672 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
1740 | 1673 |
1741 ClosureNode* closure = new ClosureNode( | 1674 ClosureNode* closure = new ClosureNode( |
1742 ident_pos, | 1675 ident_pos, Function::ZoneHandle(Z, func.extracted_method_closure()), |
1743 Function::ZoneHandle(Z, func.extracted_method_closure()), | 1676 load_receiver, NULL); |
1744 load_receiver, | |
1745 NULL); | |
1746 | 1677 |
1747 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1678 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
1748 current_block_->statements->Add(return_node); | 1679 current_block_->statements->Add(return_node); |
1749 return CloseBlock(); | 1680 return CloseBlock(); |
1750 } | 1681 } |
1751 | 1682 |
1752 | 1683 |
1753 void Parser::BuildDispatcherScope(const Function& func, | 1684 void Parser::BuildDispatcherScope(const Function& func, |
1754 const ArgumentsDescriptor& desc) { | 1685 const ArgumentsDescriptor& desc) { |
1755 ParamList params; | 1686 ParamList params; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1814 if (desc.NamedCount() > 0) { | 1745 if (desc.NamedCount() > 0) { |
1815 const Array& arg_names = | 1746 const Array& arg_names = |
1816 Array::ZoneHandle(Z, Array::New(desc.NamedCount(), Heap::kOld)); | 1747 Array::ZoneHandle(Z, Array::New(desc.NamedCount(), Heap::kOld)); |
1817 for (intptr_t i = 0; i < arg_names.Length(); ++i) { | 1748 for (intptr_t i = 0; i < arg_names.Length(); ++i) { |
1818 arg_names.SetAt(i, String::Handle(Z, desc.NameAt(i))); | 1749 arg_names.SetAt(i, String::Handle(Z, desc.NameAt(i))); |
1819 } | 1750 } |
1820 func_args->set_names(arg_names); | 1751 func_args->set_names(arg_names); |
1821 } | 1752 } |
1822 | 1753 |
1823 const String& func_name = String::ZoneHandle(Z, func.name()); | 1754 const String& func_name = String::ZoneHandle(Z, func.name()); |
1824 ArgumentListNode* arguments = BuildNoSuchMethodArguments( | 1755 ArgumentListNode* arguments = |
1825 token_pos, func_name, *func_args, NULL, false); | 1756 BuildNoSuchMethodArguments(token_pos, func_name, *func_args, NULL, false); |
1826 const intptr_t kNumArguments = 2; // Receiver, InvocationMirror. | 1757 const intptr_t kNumArguments = 2; // Receiver, InvocationMirror. |
1827 ArgumentsDescriptor args_desc( | 1758 ArgumentsDescriptor args_desc( |
1828 Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments))); | 1759 Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments))); |
1829 Function& no_such_method = Function::ZoneHandle(Z, | 1760 Function& no_such_method = Function::ZoneHandle( |
1830 Resolver::ResolveDynamicForReceiverClass(Class::Handle(Z, func.Owner()), | 1761 Z, |
1831 Symbols::NoSuchMethod(), | 1762 Resolver::ResolveDynamicForReceiverClass( |
1832 args_desc)); | 1763 Class::Handle(Z, func.Owner()), Symbols::NoSuchMethod(), args_desc)); |
1833 if (no_such_method.IsNull()) { | 1764 if (no_such_method.IsNull()) { |
1834 // If noSuchMethod(i) is not found, call Object:noSuchMethod. | 1765 // If noSuchMethod(i) is not found, call Object:noSuchMethod. |
1835 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( | 1766 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( |
1836 Class::Handle(Z, I->object_store()->object_class()), | 1767 Class::Handle(Z, I->object_store()->object_class()), |
1837 Symbols::NoSuchMethod(), | 1768 Symbols::NoSuchMethod(), args_desc); |
1838 args_desc); | |
1839 } | 1769 } |
1840 StaticCallNode* call = | 1770 StaticCallNode* call = |
1841 new StaticCallNode(token_pos, no_such_method, arguments); | 1771 new StaticCallNode(token_pos, no_such_method, arguments); |
1842 | 1772 |
1843 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1773 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1844 current_block_->statements->Add(return_node); | 1774 current_block_->statements->Add(return_node); |
1845 return CloseBlock(); | 1775 return CloseBlock(); |
1846 } | 1776 } |
1847 | 1777 |
1848 | 1778 |
1849 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { | 1779 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { |
1850 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1780 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
1851 ASSERT(func.IsInvokeFieldDispatcher()); | 1781 ASSERT(func.IsInvokeFieldDispatcher()); |
1852 TokenPosition token_pos = func.token_pos(); | 1782 TokenPosition token_pos = func.token_pos(); |
1853 ASSERT(func.token_pos() == TokenPosition::kMinSource); | 1783 ASSERT(func.token_pos() == TokenPosition::kMinSource); |
1854 ASSERT(current_class().raw() == func.Owner()); | 1784 ASSERT(current_class().raw() == func.Owner()); |
1855 | 1785 |
1856 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); | 1786 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
1857 ArgumentsDescriptor desc(args_desc); | 1787 ArgumentsDescriptor desc(args_desc); |
1858 ASSERT(desc.Count() > 0); | 1788 ASSERT(desc.Count() > 0); |
1859 | 1789 |
1860 // Set up scope for this function. | 1790 // Set up scope for this function. |
1861 BuildDispatcherScope(func, desc); | 1791 BuildDispatcherScope(func, desc); |
1862 | 1792 |
1863 // Receiver is local 0. | 1793 // Receiver is local 0. |
1864 LocalScope* scope = current_block_->scope; | 1794 LocalScope* scope = current_block_->scope; |
1865 ArgumentListNode* no_args = new ArgumentListNode(token_pos); | 1795 ArgumentListNode* no_args = new ArgumentListNode(token_pos); |
1866 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0)); | 1796 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0)); |
1867 | 1797 |
1868 const Class& closure_cls = Class::Handle( | 1798 const Class& closure_cls = |
1869 Isolate::Current()->object_store()->closure_class()); | 1799 Class::Handle(Isolate::Current()->object_store()->closure_class()); |
1870 | 1800 |
1871 const Class& owner = Class::Handle(Z, func.Owner()); | 1801 const Class& owner = Class::Handle(Z, func.Owner()); |
1872 ASSERT(!owner.IsNull()); | 1802 ASSERT(!owner.IsNull()); |
1873 const String& name = String::Handle(Z, func.name()); | 1803 const String& name = String::Handle(Z, func.name()); |
1874 AstNode* function_object = NULL; | 1804 AstNode* function_object = NULL; |
1875 if (owner.raw() == closure_cls.raw() && name.Equals(Symbols::Call())) { | 1805 if (owner.raw() == closure_cls.raw() && name.Equals(Symbols::Call())) { |
1876 function_object = receiver; | 1806 function_object = receiver; |
1877 } else { | 1807 } else { |
1878 const String& getter_name = String::ZoneHandle(Z, | 1808 const String& getter_name = |
1879 Field::GetterSymbol(name)); | 1809 String::ZoneHandle(Z, Field::GetterSymbol(name)); |
1880 function_object = new(Z) InstanceCallNode( | 1810 function_object = |
1881 token_pos, receiver, getter_name, no_args); | 1811 new (Z) InstanceCallNode(token_pos, receiver, getter_name, no_args); |
1882 } | 1812 } |
1883 | 1813 |
1884 // Pass arguments 1..n to the closure call. | 1814 // Pass arguments 1..n to the closure call. |
1885 ArgumentListNode* args = new(Z) ArgumentListNode(token_pos); | 1815 ArgumentListNode* args = new (Z) ArgumentListNode(token_pos); |
1886 const Array& names = Array::Handle( | 1816 const Array& names = |
1887 Z, Array::New(desc.NamedCount(), Heap::kOld)); | 1817 Array::Handle(Z, Array::New(desc.NamedCount(), Heap::kOld)); |
1888 // Positional parameters. | 1818 // Positional parameters. |
1889 intptr_t i = 1; | 1819 intptr_t i = 1; |
1890 for (; i < desc.PositionalCount(); ++i) { | 1820 for (; i < desc.PositionalCount(); ++i) { |
1891 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1821 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
1892 } | 1822 } |
1893 // Named parameters. | 1823 // Named parameters. |
1894 for (; i < desc.Count(); i++) { | 1824 for (; i < desc.Count(); i++) { |
1895 args->Add(new(Z) LoadLocalNode(token_pos, scope->VariableAt(i))); | 1825 args->Add(new (Z) LoadLocalNode(token_pos, scope->VariableAt(i))); |
1896 intptr_t index = i - desc.PositionalCount(); | 1826 intptr_t index = i - desc.PositionalCount(); |
1897 names.SetAt(index, String::Handle(Z, desc.NameAt(index))); | 1827 names.SetAt(index, String::Handle(Z, desc.NameAt(index))); |
1898 } | 1828 } |
1899 args->set_names(names); | 1829 args->set_names(names); |
1900 | 1830 |
1901 AstNode* result = NULL; | 1831 AstNode* result = NULL; |
1902 if (owner.raw() == closure_cls.raw() && name.Equals(Symbols::Call())) { | 1832 if (owner.raw() == closure_cls.raw() && name.Equals(Symbols::Call())) { |
1903 result = new ClosureCallNode(token_pos, function_object, args); | 1833 result = new ClosureCallNode(token_pos, function_object, args); |
1904 } else { | 1834 } else { |
1905 result = BuildClosureCall(token_pos, function_object, args); | 1835 result = BuildClosureCall(token_pos, function_object, args); |
1906 } | 1836 } |
1907 | 1837 |
1908 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1838 ReturnNode* return_node = new ReturnNode(token_pos, result); |
1909 current_block_->statements->Add(return_node); | 1839 current_block_->statements->Add(return_node); |
1910 return CloseBlock(); | 1840 return CloseBlock(); |
1911 } | 1841 } |
1912 | 1842 |
1913 | 1843 |
1914 AstNode* Parser::BuildClosureCall(TokenPosition token_pos, | 1844 AstNode* Parser::BuildClosureCall(TokenPosition token_pos, |
1915 AstNode* closure, | 1845 AstNode* closure, |
1916 ArgumentListNode* arguments) { | 1846 ArgumentListNode* arguments) { |
1917 return new InstanceCallNode(token_pos, | 1847 return new InstanceCallNode(token_pos, closure, Symbols::Call(), arguments); |
1918 closure, | |
1919 Symbols::Call(), | |
1920 arguments); | |
1921 } | 1848 } |
1922 | 1849 |
1923 | 1850 |
1924 void Parser::SkipToMatching() { | 1851 void Parser::SkipToMatching() { |
1925 Token::Kind opening_token = CurrentToken(); | 1852 Token::Kind opening_token = CurrentToken(); |
1926 ASSERT((opening_token == Token::kLBRACE) || | 1853 ASSERT((opening_token == Token::kLBRACE) || |
1927 (opening_token == Token::kLPAREN)); | 1854 (opening_token == Token::kLPAREN)); |
1928 GrowableArray<Token::Kind> token_stack(8); | 1855 GrowableArray<Token::Kind> token_stack(8); |
1929 GrowableArray<TokenPosition> token_pos_stack(8); | 1856 GrowableArray<TokenPosition> token_pos_stack(8); |
1930 // Adding the first opening brace here, because it will be consumed | 1857 // Adding the first opening brace here, because it will be consumed |
1931 // in the loop right away. | 1858 // in the loop right away. |
1932 token_stack.Add(opening_token); | 1859 token_stack.Add(opening_token); |
1933 const TokenPosition start_pos = TokenPos(); | 1860 const TokenPosition start_pos = TokenPos(); |
1934 TokenPosition opening_pos = start_pos; | 1861 TokenPosition opening_pos = start_pos; |
1935 token_pos_stack.Add(start_pos); | 1862 token_pos_stack.Add(start_pos); |
1936 bool is_match = true; | 1863 bool is_match = true; |
1937 bool unexpected_token_found = false; | 1864 bool unexpected_token_found = false; |
1938 Token::Kind token = opening_token; | 1865 Token::Kind token = opening_token; |
1939 TokenPosition token_pos; | 1866 TokenPosition token_pos; |
1940 do { | 1867 do { |
1941 ConsumeToken(); | 1868 ConsumeToken(); |
1942 token = CurrentToken(); | 1869 token = CurrentToken(); |
1943 token_pos = TokenPos(); | 1870 token_pos = TokenPos(); |
(...skipping 23 matching lines...) Expand all Loading... |
1967 opening_token = token_stack.RemoveLast(); | 1894 opening_token = token_stack.RemoveLast(); |
1968 opening_pos = token_pos_stack.RemoveLast(); | 1895 opening_pos = token_pos_stack.RemoveLast(); |
1969 unexpected_token_found = true; | 1896 unexpected_token_found = true; |
1970 break; | 1897 break; |
1971 default: | 1898 default: |
1972 // nothing. | 1899 // nothing. |
1973 break; | 1900 break; |
1974 } | 1901 } |
1975 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); | 1902 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); |
1976 if (!is_match) { | 1903 if (!is_match) { |
1977 const Error& error = Error::Handle( | 1904 const Error& error = Error::Handle(LanguageError::NewFormatted( |
1978 LanguageError::NewFormatted(Error::Handle(), | 1905 Error::Handle(), script_, opening_pos, Report::AtLocation, |
1979 script_, opening_pos, Report::AtLocation, | 1906 Report::kWarning, Heap::kNew, "unbalanced '%s' opens here", |
1980 Report::kWarning, Heap::kNew, | 1907 Token::Str(opening_token))); |
1981 "unbalanced '%s' opens here", Token::Str(opening_token))); | 1908 ReportErrors(error, script_, token_pos, "unbalanced '%s'", |
1982 ReportErrors(error, script_, token_pos, | 1909 Token::Str(token)); |
1983 "unbalanced '%s'", Token::Str(token)); | |
1984 } else if (unexpected_token_found) { | 1910 } else if (unexpected_token_found) { |
1985 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); | 1911 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); |
1986 } | 1912 } |
1987 } | 1913 } |
1988 | 1914 |
1989 | 1915 |
1990 | |
1991 void Parser::SkipBlock() { | 1916 void Parser::SkipBlock() { |
1992 ASSERT(CurrentToken() == Token::kLBRACE); | 1917 ASSERT(CurrentToken() == Token::kLBRACE); |
1993 SkipToMatching(); | 1918 SkipToMatching(); |
1994 } | 1919 } |
1995 | 1920 |
1996 | 1921 |
1997 // Skips tokens up to and including matching closing parenthesis. | 1922 // Skips tokens up to and including matching closing parenthesis. |
1998 void Parser::SkipToMatchingParenthesis() { | 1923 void Parser::SkipToMatchingParenthesis() { |
1999 ASSERT(CurrentToken() == Token::kLPAREN); | 1924 ASSERT(CurrentToken() == Token::kLPAREN); |
2000 SkipToMatching(); | 1925 SkipToMatching(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 } | 1989 } |
2065 } | 1990 } |
2066 } | 1991 } |
2067 if (found_type) { | 1992 if (found_type) { |
2068 // The types of formal parameters are never ignored, even in unchecked | 1993 // The types of formal parameters are never ignored, even in unchecked |
2069 // mode, because they are part of the function type of closurized | 1994 // mode, because they are part of the function type of closurized |
2070 // functions appearing in type tests with typedefs. | 1995 // functions appearing in type tests with typedefs. |
2071 parameter.has_explicit_type = true; | 1996 parameter.has_explicit_type = true; |
2072 // It is too early to resolve the type here, since it can be a result type | 1997 // It is too early to resolve the type here, since it can be a result type |
2073 // referring to a not yet declared function type parameter. | 1998 // referring to a not yet declared function type parameter. |
2074 parameter.type = &AbstractType::ZoneHandle(Z, | 1999 parameter.type = &AbstractType::ZoneHandle( |
2075 ParseType(ClassFinalizer::kDoNotResolve)); | 2000 Z, ParseType(ClassFinalizer::kDoNotResolve)); |
2076 } else { | 2001 } else { |
2077 // If this is an initializing formal, its type will be set to the type of | 2002 // If this is an initializing formal, its type will be set to the type of |
2078 // the respective field when the constructor is fully parsed. | 2003 // the respective field when the constructor is fully parsed. |
2079 parameter.type = &Object::dynamic_type(); | 2004 parameter.type = &Object::dynamic_type(); |
2080 } | 2005 } |
2081 } | 2006 } |
2082 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 2007 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
2083 ConsumeToken(); | 2008 ConsumeToken(); |
2084 ExpectToken(Token::kPERIOD); | 2009 ExpectToken(Token::kPERIOD); |
2085 this_seen = true; | 2010 this_seen = true; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2123 if (!var_seen && !final_seen) { | 2048 if (!var_seen && !final_seen) { |
2124 // The parsed parameter type is actually the function result type. | 2049 // The parsed parameter type is actually the function result type. |
2125 AbstractType& result_type = | 2050 AbstractType& result_type = |
2126 AbstractType::Handle(Z, parameter.type->raw()); | 2051 AbstractType::Handle(Z, parameter.type->raw()); |
2127 | 2052 |
2128 // In top-level and mixin functions, the source may be in a different | 2053 // In top-level and mixin functions, the source may be in a different |
2129 // script than the script of the current class. However, we never reparse | 2054 // script than the script of the current class. However, we never reparse |
2130 // signature functions (except typedef signature functions), therefore | 2055 // signature functions (except typedef signature functions), therefore |
2131 // we do not need to keep the correct script via a patch class. Use the | 2056 // we do not need to keep the correct script via a patch class. Use the |
2132 // actual current class as owner of the signature function. | 2057 // actual current class as owner of the signature function. |
2133 const Function& signature_function = Function::Handle(Z, | 2058 const Function& signature_function = |
2134 Function::NewSignatureFunction(current_class(), | 2059 Function::Handle(Z, Function::NewSignatureFunction( |
2135 TokenPosition::kNoSource)); | 2060 current_class(), TokenPosition::kNoSource)); |
2136 signature_function.set_parent_function(innermost_function()); | 2061 signature_function.set_parent_function(innermost_function()); |
2137 innermost_function_ = signature_function.raw(); | 2062 innermost_function_ = signature_function.raw(); |
2138 | 2063 |
2139 // Finish parsing the function type parameter. | 2064 // Finish parsing the function type parameter. |
2140 if (CurrentToken() == Token::kLT) { | 2065 if (CurrentToken() == Token::kLT) { |
2141 if (!FLAG_generic_method_syntax) { | 2066 if (!FLAG_generic_method_syntax) { |
2142 ReportError("generic function types not supported"); | 2067 ReportError("generic function types not supported"); |
2143 } | 2068 } |
2144 ParseTypeParameters(false); // Not parameterizing class, but function. | 2069 ParseTypeParameters(false); // Not parameterizing class, but function. |
2145 } | 2070 } |
2146 | 2071 |
2147 // Now that type parameters are declared, the result type can be resolved. | 2072 // Now that type parameters are declared, the result type can be resolved. |
2148 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); | 2073 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); |
2149 | 2074 |
2150 ASSERT(CurrentToken() == Token::kLPAREN); | 2075 ASSERT(CurrentToken() == Token::kLPAREN); |
2151 ParamList func_params; | 2076 ParamList func_params; |
2152 | 2077 |
2153 // Add implicit closure object parameter. | 2078 // Add implicit closure object parameter. |
2154 func_params.AddFinalParameter( | 2079 func_params.AddFinalParameter(TokenPos(), &Symbols::ClosureParameter(), |
2155 TokenPos(), | 2080 &Object::dynamic_type()); |
2156 &Symbols::ClosureParameter(), | |
2157 &Object::dynamic_type()); | |
2158 | 2081 |
2159 const bool no_explicit_default_values = false; | 2082 const bool no_explicit_default_values = false; |
2160 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 2083 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
2161 | 2084 |
2162 signature_function.set_result_type(result_type); | 2085 signature_function.set_result_type(result_type); |
2163 AddFormalParamsToFunction(&func_params, signature_function); | 2086 AddFormalParamsToFunction(&func_params, signature_function); |
2164 | 2087 |
2165 ASSERT(innermost_function().raw() == signature_function.raw()); | 2088 ASSERT(innermost_function().raw() == signature_function.raw()); |
2166 innermost_function_ = signature_function.parent_function(); | 2089 innermost_function_ = signature_function.parent_function(); |
2167 signature_function.set_data(Object::Handle(Z)); | 2090 signature_function.set_data(Object::Handle(Z)); |
(...skipping 12 matching lines...) Expand all Loading... |
2180 ASSERT(!signature_type.IsMalbounded()); | 2103 ASSERT(!signature_type.IsMalbounded()); |
2181 // The type of the parameter is now the signature type. | 2104 // The type of the parameter is now the signature type. |
2182 parameter.type = &signature_type; | 2105 parameter.type = &signature_type; |
2183 } | 2106 } |
2184 } else { | 2107 } else { |
2185 if (!parameter.type->IsFinalized()) { | 2108 if (!parameter.type->IsFinalized()) { |
2186 AbstractType& type = AbstractType::ZoneHandle(Z, parameter.type->raw()); | 2109 AbstractType& type = AbstractType::ZoneHandle(Z, parameter.type->raw()); |
2187 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); | 2110 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); |
2188 if (!is_top_level_) { | 2111 if (!is_top_level_) { |
2189 type = ClassFinalizer::FinalizeType( | 2112 type = ClassFinalizer::FinalizeType( |
2190 Class::Handle(Z, innermost_function().origin()), | 2113 Class::Handle(Z, innermost_function().origin()), type, |
2191 type, | |
2192 ClassFinalizer::kCanonicalize); | 2114 ClassFinalizer::kCanonicalize); |
2193 } | 2115 } |
2194 parameter.type = &type; | 2116 parameter.type = &type; |
2195 } | 2117 } |
2196 } | 2118 } |
2197 | 2119 |
2198 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) { | 2120 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) { |
2199 if ((!params->has_optional_positional_parameters && | 2121 if ((!params->has_optional_positional_parameters && |
2200 !params->has_optional_named_parameters) || | 2122 !params->has_optional_named_parameters) || |
2201 !allow_explicit_default_value) { | 2123 !allow_explicit_default_value) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2254 params->has_optional_positional_parameters = true; | 2176 params->has_optional_positional_parameters = true; |
2255 return; | 2177 return; |
2256 } | 2178 } |
2257 if (!params->has_optional_positional_parameters && | 2179 if (!params->has_optional_positional_parameters && |
2258 !params->has_optional_named_parameters && | 2180 !params->has_optional_named_parameters && |
2259 (CurrentToken() == Token::kLBRACE)) { | 2181 (CurrentToken() == Token::kLBRACE)) { |
2260 // End of normal parameters, start of optional named parameters. | 2182 // End of normal parameters, start of optional named parameters. |
2261 params->has_optional_named_parameters = true; | 2183 params->has_optional_named_parameters = true; |
2262 return; | 2184 return; |
2263 } | 2185 } |
2264 Token::Kind terminator = | 2186 Token::Kind terminator = params->has_optional_positional_parameters |
2265 params->has_optional_positional_parameters ? Token::kRBRACK : | 2187 ? Token::kRBRACK |
2266 params->has_optional_named_parameters ? Token::kRBRACE : | 2188 : params->has_optional_named_parameters |
2267 Token :: kRPAREN; | 2189 ? Token::kRBRACE |
| 2190 : Token::kRPAREN; |
2268 if (has_seen_parameter && CurrentToken() == terminator) { | 2191 if (has_seen_parameter && CurrentToken() == terminator) { |
2269 // Allow a trailing comma. | 2192 // Allow a trailing comma. |
2270 break; | 2193 break; |
2271 } | 2194 } |
2272 ParseFormalParameter(allow_explicit_default_values, | 2195 ParseFormalParameter(allow_explicit_default_values, evaluate_metadata, |
2273 evaluate_metadata, | |
2274 params); | 2196 params); |
2275 has_seen_parameter = true; | 2197 has_seen_parameter = true; |
2276 } while (CurrentToken() == Token::kCOMMA); | 2198 } while (CurrentToken() == Token::kCOMMA); |
2277 } | 2199 } |
2278 | 2200 |
2279 | 2201 |
2280 void Parser::ParseFormalParameterList(bool allow_explicit_default_values, | 2202 void Parser::ParseFormalParameterList(bool allow_explicit_default_values, |
2281 bool evaluate_metadata, | 2203 bool evaluate_metadata, |
2282 ParamList* params) { | 2204 ParamList* params) { |
2283 TRACE_PARSER("ParseFormalParameterList"); | 2205 TRACE_PARSER("ParseFormalParameterList"); |
2284 ASSERT(CurrentToken() == Token::kLPAREN); | 2206 ASSERT(CurrentToken() == Token::kLPAREN); |
2285 | 2207 |
2286 if (LookaheadToken(1) != Token::kRPAREN) { | 2208 if (LookaheadToken(1) != Token::kRPAREN) { |
2287 // Parse fixed parameters. | 2209 // Parse fixed parameters. |
2288 ParseFormalParameters(allow_explicit_default_values, | 2210 ParseFormalParameters(allow_explicit_default_values, evaluate_metadata, |
2289 evaluate_metadata, | |
2290 params); | 2211 params); |
2291 if (params->has_optional_positional_parameters || | 2212 if (params->has_optional_positional_parameters || |
2292 params->has_optional_named_parameters) { | 2213 params->has_optional_named_parameters) { |
2293 // Parse optional parameters. | 2214 // Parse optional parameters. |
2294 ParseFormalParameters(allow_explicit_default_values, | 2215 ParseFormalParameters(allow_explicit_default_values, evaluate_metadata, |
2295 evaluate_metadata, | |
2296 params); | 2216 params); |
2297 if (params->has_optional_positional_parameters) { | 2217 if (params->has_optional_positional_parameters) { |
2298 CheckToken(Token::kRBRACK, "',' or ']' expected"); | 2218 CheckToken(Token::kRBRACK, "',' or ']' expected"); |
2299 } else { | 2219 } else { |
2300 CheckToken(Token::kRBRACE, "',' or '}' expected"); | 2220 CheckToken(Token::kRBRACE, "',' or '}' expected"); |
2301 } | 2221 } |
2302 ConsumeToken(); // ']' or '}'. | 2222 ConsumeToken(); // ']' or '}'. |
2303 } | 2223 } |
2304 if ((CurrentToken() != Token::kRPAREN) && | 2224 if ((CurrentToken() != Token::kRPAREN) && |
2305 !params->has_optional_positional_parameters && | 2225 !params->has_optional_positional_parameters && |
(...skipping 25 matching lines...) Expand all Loading... |
2331 RawFunction* Parser::GetSuperFunction(TokenPosition token_pos, | 2251 RawFunction* Parser::GetSuperFunction(TokenPosition token_pos, |
2332 const String& name, | 2252 const String& name, |
2333 ArgumentListNode* arguments, | 2253 ArgumentListNode* arguments, |
2334 bool resolve_getter, | 2254 bool resolve_getter, |
2335 bool* is_no_such_method) { | 2255 bool* is_no_such_method) { |
2336 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); | 2256 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
2337 if (super_class.IsNull()) { | 2257 if (super_class.IsNull()) { |
2338 ReportError(token_pos, "class '%s' does not have a superclass", | 2258 ReportError(token_pos, "class '%s' does not have a superclass", |
2339 String::Handle(Z, current_class().Name()).ToCString()); | 2259 String::Handle(Z, current_class().Name()).ToCString()); |
2340 } | 2260 } |
2341 Function& super_func = Function::Handle(Z, | 2261 Function& super_func = Function::Handle( |
2342 Resolver::ResolveDynamicAnyArgs(Z, super_class, name)); | 2262 Z, Resolver::ResolveDynamicAnyArgs(Z, super_class, name)); |
2343 if (!super_func.IsNull() && | 2263 if (!super_func.IsNull() && |
2344 !super_func.AreValidArguments(arguments->length(), | 2264 !super_func.AreValidArguments(arguments->length(), arguments->names(), |
2345 arguments->names(), | |
2346 NULL)) { | 2265 NULL)) { |
2347 super_func = Function::null(); | 2266 super_func = Function::null(); |
2348 } else if (super_func.IsNull() && resolve_getter) { | 2267 } else if (super_func.IsNull() && resolve_getter) { |
2349 const String& getter_name = String::ZoneHandle(Z, Field::GetterName(name)); | 2268 const String& getter_name = String::ZoneHandle(Z, Field::GetterName(name)); |
2350 super_func = Resolver::ResolveDynamicAnyArgs(Z, super_class, getter_name); | 2269 super_func = Resolver::ResolveDynamicAnyArgs(Z, super_class, getter_name); |
2351 ASSERT(super_func.IsNull() || | 2270 ASSERT(super_func.IsNull() || |
2352 (super_func.kind() != RawFunction::kImplicitStaticFinalGetter)); | 2271 (super_func.kind() != RawFunction::kImplicitStaticFinalGetter)); |
2353 } | 2272 } |
2354 if (super_func.IsNull()) { | 2273 if (super_func.IsNull()) { |
2355 super_func = Resolver::ResolveDynamicAnyArgs(Z, | 2274 super_func = Resolver::ResolveDynamicAnyArgs(Z, super_class, |
2356 super_class, Symbols::NoSuchMethod()); | 2275 Symbols::NoSuchMethod()); |
2357 ASSERT(!super_func.IsNull()); | 2276 ASSERT(!super_func.IsNull()); |
2358 *is_no_such_method = true; | 2277 *is_no_such_method = true; |
2359 } else { | 2278 } else { |
2360 *is_no_such_method = false; | 2279 *is_no_such_method = false; |
2361 } | 2280 } |
2362 return super_func.raw(); | 2281 return super_func.raw(); |
2363 } | 2282 } |
2364 | 2283 |
2365 | 2284 |
2366 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 2285 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
2367 TokenPosition call_pos, | 2286 TokenPosition call_pos, |
2368 const String& function_name, | 2287 const String& function_name, |
2369 const ArgumentListNode& function_args, | 2288 const ArgumentListNode& function_args, |
2370 const LocalVariable* temp_for_last_arg, | 2289 const LocalVariable* temp_for_last_arg, |
2371 bool is_super_invocation) { | 2290 bool is_super_invocation) { |
2372 const TokenPosition args_pos = function_args.token_pos(); | 2291 const TokenPosition args_pos = function_args.token_pos(); |
2373 // Build arguments to the call to the static | 2292 // Build arguments to the call to the static |
2374 // InvocationMirror._allocateInvocationMirror method. | 2293 // InvocationMirror._allocateInvocationMirror method. |
2375 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2294 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
2376 // The first argument is the original function name. | 2295 // The first argument is the original function name. |
2377 arguments->Add(new LiteralNode(args_pos, function_name)); | 2296 arguments->Add(new LiteralNode(args_pos, function_name)); |
2378 // The second argument is the arguments descriptor of the original function. | 2297 // The second argument is the arguments descriptor of the original function. |
2379 const Array& args_descriptor = | 2298 const Array& args_descriptor = Array::ZoneHandle( |
2380 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), | 2299 ArgumentsDescriptor::New(function_args.length(), function_args.names())); |
2381 function_args.names())); | |
2382 arguments->Add(new LiteralNode(args_pos, args_descriptor)); | 2300 arguments->Add(new LiteralNode(args_pos, args_descriptor)); |
2383 // The third argument is an array containing the original function arguments, | 2301 // The third argument is an array containing the original function arguments, |
2384 // including the receiver. | 2302 // including the receiver. |
2385 ArrayNode* args_array = | 2303 ArrayNode* args_array = |
2386 new ArrayNode(args_pos, Type::ZoneHandle(Type::ArrayType())); | 2304 new ArrayNode(args_pos, Type::ZoneHandle(Type::ArrayType())); |
2387 for (intptr_t i = 0; i < function_args.length(); i++) { | 2305 for (intptr_t i = 0; i < function_args.length(); i++) { |
2388 AstNode* arg = function_args.NodeAt(i); | 2306 AstNode* arg = function_args.NodeAt(i); |
2389 if ((temp_for_last_arg != NULL) && (i == function_args.length() - 1)) { | 2307 if ((temp_for_last_arg != NULL) && (i == function_args.length() - 1)) { |
2390 LetNode* store_arg = new LetNode(arg->token_pos()); | 2308 LetNode* store_arg = new LetNode(arg->token_pos()); |
2391 store_arg->AddNode(new StoreLocalNode(arg->token_pos(), | 2309 store_arg->AddNode( |
2392 temp_for_last_arg, | 2310 new StoreLocalNode(arg->token_pos(), temp_for_last_arg, arg)); |
2393 arg)); | 2311 store_arg->AddNode( |
2394 store_arg->AddNode(new LoadLocalNode(arg->token_pos(), | 2312 new LoadLocalNode(arg->token_pos(), temp_for_last_arg)); |
2395 temp_for_last_arg)); | |
2396 args_array->AddElement(store_arg); | 2313 args_array->AddElement(store_arg); |
2397 } else { | 2314 } else { |
2398 args_array->AddElement(arg); | 2315 args_array->AddElement(arg); |
2399 } | 2316 } |
2400 } | 2317 } |
2401 arguments->Add(args_array); | 2318 arguments->Add(args_array); |
2402 arguments->Add(new LiteralNode(args_pos, Bool::Get(is_super_invocation))); | 2319 arguments->Add(new LiteralNode(args_pos, Bool::Get(is_super_invocation))); |
2403 // Lookup the static InvocationMirror._allocateInvocationMirror method. | 2320 // Lookup the static InvocationMirror._allocateInvocationMirror method. |
2404 const Class& mirror_class = | 2321 const Class& mirror_class = |
2405 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); | 2322 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); |
2406 ASSERT(!mirror_class.IsNull()); | 2323 ASSERT(!mirror_class.IsNull()); |
2407 const Function& allocation_function = Function::ZoneHandle( | 2324 const Function& allocation_function = |
2408 mirror_class.LookupStaticFunction( | 2325 Function::ZoneHandle(mirror_class.LookupStaticFunction( |
2409 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); | 2326 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); |
2410 ASSERT(!allocation_function.IsNull()); | 2327 ASSERT(!allocation_function.IsNull()); |
2411 return new StaticCallNode(call_pos, allocation_function, arguments); | 2328 return new StaticCallNode(call_pos, allocation_function, arguments); |
2412 } | 2329 } |
2413 | 2330 |
2414 | 2331 |
2415 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 2332 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
2416 TokenPosition call_pos, | 2333 TokenPosition call_pos, |
2417 const String& function_name, | 2334 const String& function_name, |
2418 const ArgumentListNode& function_args, | 2335 const ArgumentListNode& function_args, |
2419 const LocalVariable* temp_for_last_arg, | 2336 const LocalVariable* temp_for_last_arg, |
2420 bool is_super_invocation) { | 2337 bool is_super_invocation) { |
2421 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 2338 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
2422 const TokenPosition args_pos = function_args.token_pos(); | 2339 const TokenPosition args_pos = function_args.token_pos(); |
2423 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2340 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
2424 arguments->Add(function_args.NodeAt(0)); | 2341 arguments->Add(function_args.NodeAt(0)); |
2425 // The second argument is the invocation mirror. | 2342 // The second argument is the invocation mirror. |
2426 arguments->Add(BuildInvocationMirrorAllocation(call_pos, | 2343 arguments->Add( |
2427 function_name, | 2344 BuildInvocationMirrorAllocation(call_pos, function_name, function_args, |
2428 function_args, | 2345 temp_for_last_arg, is_super_invocation)); |
2429 temp_for_last_arg, | |
2430 is_super_invocation)); | |
2431 return arguments; | 2346 return arguments; |
2432 } | 2347 } |
2433 | 2348 |
2434 | 2349 |
2435 AstNode* Parser::ParseSuperCall(const String& function_name) { | 2350 AstNode* Parser::ParseSuperCall(const String& function_name) { |
2436 TRACE_PARSER("ParseSuperCall"); | 2351 TRACE_PARSER("ParseSuperCall"); |
2437 ASSERT(CurrentToken() == Token::kLPAREN); | 2352 ASSERT(CurrentToken() == Token::kLPAREN); |
2438 const TokenPosition supercall_pos = TokenPos(); | 2353 const TokenPosition supercall_pos = TokenPos(); |
2439 | 2354 |
2440 // 'this' parameter is the first argument to super call. | 2355 // 'this' parameter is the first argument to super call. |
2441 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2356 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
2442 AstNode* receiver = LoadReceiver(supercall_pos); | 2357 AstNode* receiver = LoadReceiver(supercall_pos); |
2443 arguments->Add(receiver); | 2358 arguments->Add(receiver); |
2444 ParseActualParameters(arguments, kAllowConst); | 2359 ParseActualParameters(arguments, kAllowConst); |
2445 | 2360 |
2446 const bool kResolveGetter = true; | 2361 const bool kResolveGetter = true; |
2447 bool is_no_such_method = false; | 2362 bool is_no_such_method = false; |
2448 const Function& super_function = Function::ZoneHandle(Z, | 2363 const Function& super_function = Function::ZoneHandle( |
2449 GetSuperFunction(supercall_pos, | 2364 Z, GetSuperFunction(supercall_pos, function_name, arguments, |
2450 function_name, | 2365 kResolveGetter, &is_no_such_method)); |
2451 arguments, | |
2452 kResolveGetter, | |
2453 &is_no_such_method)); | |
2454 if (super_function.IsGetterFunction() || | 2366 if (super_function.IsGetterFunction() || |
2455 super_function.IsImplicitGetterFunction()) { | 2367 super_function.IsImplicitGetterFunction()) { |
2456 const Class& super_class = | 2368 const Class& super_class = |
2457 Class::ZoneHandle(Z, current_class().SuperClass()); | 2369 Class::ZoneHandle(Z, current_class().SuperClass()); |
2458 AstNode* closure = new StaticGetterNode(supercall_pos, | 2370 AstNode* closure = new StaticGetterNode( |
2459 LoadReceiver(supercall_pos), | 2371 supercall_pos, LoadReceiver(supercall_pos), super_class, function_name); |
2460 super_class, | |
2461 function_name); | |
2462 // 'this' is not passed as parameter to the closure. | 2372 // 'this' is not passed as parameter to the closure. |
2463 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); | 2373 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); |
2464 for (int i = 1; i < arguments->length(); i++) { | 2374 for (int i = 1; i < arguments->length(); i++) { |
2465 closure_arguments->Add(arguments->NodeAt(i)); | 2375 closure_arguments->Add(arguments->NodeAt(i)); |
2466 } | 2376 } |
2467 return BuildClosureCall(supercall_pos, closure, closure_arguments); | 2377 return BuildClosureCall(supercall_pos, closure, closure_arguments); |
2468 } | 2378 } |
2469 if (is_no_such_method) { | 2379 if (is_no_such_method) { |
2470 arguments = BuildNoSuchMethodArguments( | 2380 arguments = BuildNoSuchMethodArguments(supercall_pos, function_name, |
2471 supercall_pos, function_name, *arguments, NULL, true); | 2381 *arguments, NULL, true); |
2472 } | 2382 } |
2473 return new StaticCallNode(supercall_pos, super_function, arguments); | 2383 return new StaticCallNode(supercall_pos, super_function, arguments); |
2474 } | 2384 } |
2475 | 2385 |
2476 | 2386 |
2477 // Simple test if a node is side effect free. | 2387 // Simple test if a node is side effect free. |
2478 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 2388 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
2479 return node->IsLiteralNode() || node->IsLoadLocalNode(); | 2389 return node->IsLiteralNode() || node->IsLoadLocalNode(); |
2480 } | 2390 } |
2481 | 2391 |
2482 | 2392 |
2483 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 2393 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
2484 ASSERT(super->IsSuper()); | 2394 ASSERT(super->IsSuper()); |
2485 AstNode* super_op = NULL; | 2395 AstNode* super_op = NULL; |
2486 const TokenPosition super_pos = super->token_pos(); | 2396 const TokenPosition super_pos = super->token_pos(); |
2487 if ((op == Token::kNEGATE) || | 2397 if ((op == Token::kNEGATE) || (op == Token::kBIT_NOT)) { |
2488 (op == Token::kBIT_NOT)) { | |
2489 // Resolve the operator function in the superclass. | 2398 // Resolve the operator function in the superclass. |
2490 const String& operator_function_name = Symbols::Token(op); | 2399 const String& operator_function_name = Symbols::Token(op); |
2491 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 2400 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
2492 AstNode* receiver = LoadReceiver(super_pos); | 2401 AstNode* receiver = LoadReceiver(super_pos); |
2493 op_arguments->Add(receiver); | 2402 op_arguments->Add(receiver); |
2494 const bool kResolveGetter = false; | 2403 const bool kResolveGetter = false; |
2495 bool is_no_such_method = false; | 2404 bool is_no_such_method = false; |
2496 const Function& super_operator = Function::ZoneHandle(Z, | 2405 const Function& super_operator = Function::ZoneHandle( |
2497 GetSuperFunction(super_pos, | 2406 Z, GetSuperFunction(super_pos, operator_function_name, op_arguments, |
2498 operator_function_name, | 2407 kResolveGetter, &is_no_such_method)); |
2499 op_arguments, | |
2500 kResolveGetter, | |
2501 &is_no_such_method)); | |
2502 if (is_no_such_method) { | 2408 if (is_no_such_method) { |
2503 op_arguments = BuildNoSuchMethodArguments( | 2409 op_arguments = BuildNoSuchMethodArguments( |
2504 super_pos, operator_function_name, *op_arguments, NULL, true); | 2410 super_pos, operator_function_name, *op_arguments, NULL, true); |
2505 } | 2411 } |
2506 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 2412 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
2507 } else { | 2413 } else { |
2508 ReportError(super_pos, "illegal super operator call"); | 2414 ReportError(super_pos, "illegal super operator call"); |
2509 } | 2415 } |
2510 return super_op; | 2416 return super_op; |
2511 } | 2417 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2543 | 2449 |
2544 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); | 2450 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); |
2545 AstNode* receiver = LoadReceiver(operator_pos); | 2451 AstNode* receiver = LoadReceiver(operator_pos); |
2546 op_arguments->Add(receiver); | 2452 op_arguments->Add(receiver); |
2547 op_arguments->Add(other_operand); | 2453 op_arguments->Add(other_operand); |
2548 | 2454 |
2549 // Resolve the operator function in the superclass. | 2455 // Resolve the operator function in the superclass. |
2550 const String& operator_function_name = Symbols::Token(op); | 2456 const String& operator_function_name = Symbols::Token(op); |
2551 const bool kResolveGetter = false; | 2457 const bool kResolveGetter = false; |
2552 bool is_no_such_method = false; | 2458 bool is_no_such_method = false; |
2553 const Function& super_operator = Function::ZoneHandle(Z, | 2459 const Function& super_operator = Function::ZoneHandle( |
2554 GetSuperFunction(operator_pos, | 2460 Z, GetSuperFunction(operator_pos, operator_function_name, op_arguments, |
2555 operator_function_name, | 2461 kResolveGetter, &is_no_such_method)); |
2556 op_arguments, | |
2557 kResolveGetter, | |
2558 &is_no_such_method)); | |
2559 if (is_no_such_method) { | 2462 if (is_no_such_method) { |
2560 op_arguments = BuildNoSuchMethodArguments( | 2463 op_arguments = BuildNoSuchMethodArguments( |
2561 operator_pos, operator_function_name, *op_arguments, NULL, true); | 2464 operator_pos, operator_function_name, *op_arguments, NULL, true); |
2562 } | 2465 } |
2563 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2466 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
2564 if (negate_result) { | 2467 if (negate_result) { |
2565 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2468 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
2566 } | 2469 } |
2567 } | 2470 } |
2568 return super_op; | 2471 return super_op; |
(...skipping 23 matching lines...) Expand all Loading... |
2592 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); | 2495 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); |
2593 Function& super_getter = Function::ZoneHandle(Z); | 2496 Function& super_getter = Function::ZoneHandle(Z); |
2594 if (!getter_name.IsNull()) { | 2497 if (!getter_name.IsNull()) { |
2595 super_getter = Resolver::ResolveDynamicAnyArgs(Z, super_class, getter_name); | 2498 super_getter = Resolver::ResolveDynamicAnyArgs(Z, super_class, getter_name); |
2596 } | 2499 } |
2597 if (super_getter.IsNull()) { | 2500 if (super_getter.IsNull()) { |
2598 const String& setter_name = | 2501 const String& setter_name = |
2599 String::ZoneHandle(Z, Field::LookupSetterSymbol(field_name)); | 2502 String::ZoneHandle(Z, Field::LookupSetterSymbol(field_name)); |
2600 Function& super_setter = Function::ZoneHandle(Z); | 2503 Function& super_setter = Function::ZoneHandle(Z); |
2601 if (!setter_name.IsNull()) { | 2504 if (!setter_name.IsNull()) { |
2602 super_setter = Resolver::ResolveDynamicAnyArgs(Z, | 2505 super_setter = |
2603 super_class, setter_name); | 2506 Resolver::ResolveDynamicAnyArgs(Z, super_class, setter_name); |
2604 } | 2507 } |
2605 if (super_setter.IsNull()) { | 2508 if (super_setter.IsNull()) { |
2606 // Check if this is an access to an implicit closure using 'super'. | 2509 // Check if this is an access to an implicit closure using 'super'. |
2607 // If a function exists of the specified field_name then try | 2510 // If a function exists of the specified field_name then try |
2608 // accessing it as a getter, at runtime we will handle this by | 2511 // accessing it as a getter, at runtime we will handle this by |
2609 // creating an implicit closure of the function and returning it. | 2512 // creating an implicit closure of the function and returning it. |
2610 const Function& super_function = Function::ZoneHandle(Z, | 2513 const Function& super_function = Function::ZoneHandle( |
2611 Resolver::ResolveDynamicAnyArgs(Z, super_class, field_name)); | 2514 Z, Resolver::ResolveDynamicAnyArgs(Z, super_class, field_name)); |
2612 if (!super_function.IsNull()) { | 2515 if (!super_function.IsNull()) { |
2613 // In case CreateAssignmentNode is called later on this | 2516 // In case CreateAssignmentNode is called later on this |
2614 // CreateImplicitClosureNode, it will be replaced by a StaticSetterNode. | 2517 // CreateImplicitClosureNode, it will be replaced by a StaticSetterNode. |
2615 return CreateImplicitClosureNode(super_function, | 2518 return CreateImplicitClosureNode(super_function, field_pos, |
2616 field_pos, | |
2617 implicit_argument); | 2519 implicit_argument); |
2618 } | 2520 } |
2619 // No function or field exists of the specified field_name. | 2521 // No function or field exists of the specified field_name. |
2620 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2522 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
2621 } | 2523 } |
2622 } | 2524 } |
2623 return new(Z) StaticGetterNode( | 2525 return new (Z) |
2624 field_pos, implicit_argument, super_class, field_name); | 2526 StaticGetterNode(field_pos, implicit_argument, super_class, field_name); |
2625 } | 2527 } |
2626 | 2528 |
2627 | 2529 |
2628 StaticCallNode* Parser::GenerateSuperConstructorCall( | 2530 StaticCallNode* Parser::GenerateSuperConstructorCall( |
2629 const Class& cls, | 2531 const Class& cls, |
2630 TokenPosition supercall_pos, | 2532 TokenPosition supercall_pos, |
2631 LocalVariable* receiver, | 2533 LocalVariable* receiver, |
2632 ArgumentListNode* forwarding_args) { | 2534 ArgumentListNode* forwarding_args) { |
2633 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2535 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2634 // Omit the implicit super() if there is no super class (i.e. | 2536 // Omit the implicit super() if there is no super class (i.e. |
2635 // we're not compiling class Object), or if the super class is an | 2537 // we're not compiling class Object), or if the super class is an |
2636 // artificially generated "wrapper class" that has no constructor. | 2538 // artificially generated "wrapper class" that has no constructor. |
2637 if (super_class.IsNull() || | 2539 if (super_class.IsNull() || |
2638 (super_class.num_native_fields() > 0 && | 2540 (super_class.num_native_fields() > 0 && |
2639 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { | 2541 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { |
2640 return NULL; | 2542 return NULL; |
2641 } | 2543 } |
2642 String& super_ctor_name = String::Handle(Z, super_class.Name()); | 2544 String& super_ctor_name = String::Handle(Z, super_class.Name()); |
2643 super_ctor_name = Symbols::FromDot(T, super_ctor_name); | 2545 super_ctor_name = Symbols::FromDot(T, super_ctor_name); |
2644 | 2546 |
2645 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2547 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
2646 // Implicit 'this' parameter is the first argument. | 2548 // Implicit 'this' parameter is the first argument. |
2647 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2549 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
2648 arguments->Add(implicit_argument); | 2550 arguments->Add(implicit_argument); |
2649 | 2551 |
2650 // If this is a super call in a forwarding constructor, add the user- | 2552 // If this is a super call in a forwarding constructor, add the user- |
2651 // defined arguments to the super call and adjust the super | 2553 // defined arguments to the super call and adjust the super |
2652 // constructor name to the respective named constructor if necessary. | 2554 // constructor name to the respective named constructor if necessary. |
2653 if (forwarding_args != NULL) { | 2555 if (forwarding_args != NULL) { |
2654 for (int i = 0; i < forwarding_args->length(); i++) { | 2556 for (int i = 0; i < forwarding_args->length(); i++) { |
2655 arguments->Add(forwarding_args->NodeAt(i)); | 2557 arguments->Add(forwarding_args->NodeAt(i)); |
2656 } | 2558 } |
2657 String& ctor_name = String::Handle(Z, current_function().name()); | 2559 String& ctor_name = String::Handle(Z, current_function().name()); |
2658 String& class_name = String::Handle(Z, cls.Name()); | 2560 String& class_name = String::Handle(Z, cls.Name()); |
2659 if (ctor_name.Length() > class_name.Length() + 1) { | 2561 if (ctor_name.Length() > class_name.Length() + 1) { |
2660 // Generating a forwarding call to a named constructor 'C.n'. | 2562 // Generating a forwarding call to a named constructor 'C.n'. |
2661 // Add the constructor name 'n' to the super constructor. | 2563 // Add the constructor name 'n' to the super constructor. |
2662 const intptr_t kLen = class_name.Length() + 1; | 2564 const intptr_t kLen = class_name.Length() + 1; |
2663 ctor_name = Symbols::New(T, ctor_name, kLen, ctor_name.Length() - kLen); | 2565 ctor_name = Symbols::New(T, ctor_name, kLen, ctor_name.Length() - kLen); |
2664 super_ctor_name = Symbols::FromConcat(T, super_ctor_name, ctor_name); | 2566 super_ctor_name = Symbols::FromConcat(T, super_ctor_name, ctor_name); |
2665 } | 2567 } |
2666 } | 2568 } |
2667 | 2569 |
2668 // Resolve super constructor function and check arguments. | 2570 // Resolve super constructor function and check arguments. |
2669 const Function& super_ctor = Function::ZoneHandle(Z, | 2571 const Function& super_ctor = |
2670 super_class.LookupConstructor(super_ctor_name)); | 2572 Function::ZoneHandle(Z, super_class.LookupConstructor(super_ctor_name)); |
2671 if (super_ctor.IsNull()) { | 2573 if (super_ctor.IsNull()) { |
2672 ReportError(supercall_pos, | 2574 ReportError(supercall_pos, |
2673 "unresolved implicit call to super constructor '%s()'", | 2575 "unresolved implicit call to super constructor '%s()'", |
2674 String::Handle(Z, super_class.Name()).ToCString()); | 2576 String::Handle(Z, super_class.Name()).ToCString()); |
2675 } | 2577 } |
2676 if (current_function().is_const() && !super_ctor.is_const()) { | 2578 if (current_function().is_const() && !super_ctor.is_const()) { |
2677 ReportError(supercall_pos, "implicit call to non-const super constructor"); | 2579 ReportError(supercall_pos, "implicit call to non-const super constructor"); |
2678 } | 2580 } |
2679 | 2581 |
2680 String& error_message = String::Handle(Z); | 2582 String& error_message = String::Handle(Z); |
2681 if (!super_ctor.AreValidArguments(arguments->length(), | 2583 if (!super_ctor.AreValidArguments(arguments->length(), arguments->names(), |
2682 arguments->names(), | |
2683 &error_message)) { | 2584 &error_message)) { |
2684 ReportError(supercall_pos, | 2585 ReportError(supercall_pos, |
2685 "invalid arguments passed to super constructor '%s()': %s", | 2586 "invalid arguments passed to super constructor '%s()': %s", |
2686 String::Handle(Z, super_class.Name()).ToCString(), | 2587 String::Handle(Z, super_class.Name()).ToCString(), |
2687 error_message.ToCString()); | 2588 error_message.ToCString()); |
2688 } | 2589 } |
2689 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2590 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2690 } | 2591 } |
2691 | 2592 |
2692 | 2593 |
2693 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, | 2594 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, |
2694 LocalVariable* receiver) { | 2595 LocalVariable* receiver) { |
2695 TRACE_PARSER("ParseSuperInitializer"); | 2596 TRACE_PARSER("ParseSuperInitializer"); |
2696 ASSERT(CurrentToken() == Token::kSUPER); | 2597 ASSERT(CurrentToken() == Token::kSUPER); |
2697 const TokenPosition supercall_pos = TokenPos(); | 2598 const TokenPosition supercall_pos = TokenPos(); |
2698 ConsumeToken(); | 2599 ConsumeToken(); |
2699 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2600 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2700 ASSERT(!super_class.IsNull()); | 2601 ASSERT(!super_class.IsNull()); |
2701 String& ctor_name = String::Handle(Z, super_class.Name()); | 2602 String& ctor_name = String::Handle(Z, super_class.Name()); |
2702 ctor_name = Symbols::FromConcat(T, ctor_name, Symbols::Dot()); | 2603 ctor_name = Symbols::FromConcat(T, ctor_name, Symbols::Dot()); |
2703 if (CurrentToken() == Token::kPERIOD) { | 2604 if (CurrentToken() == Token::kPERIOD) { |
2704 ConsumeToken(); | 2605 ConsumeToken(); |
2705 ctor_name = Symbols::FromConcat(T, | 2606 ctor_name = Symbols::FromConcat( |
2706 ctor_name, *ExpectIdentifier("constructor name expected")); | 2607 T, ctor_name, *ExpectIdentifier("constructor name expected")); |
2707 } | 2608 } |
2708 CheckToken(Token::kLPAREN, "parameter list expected"); | 2609 CheckToken(Token::kLPAREN, "parameter list expected"); |
2709 | 2610 |
2710 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2611 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
2711 // 'this' parameter is the first argument to super class constructor. | 2612 // 'this' parameter is the first argument to super class constructor. |
2712 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2613 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
2713 arguments->Add(implicit_argument); | 2614 arguments->Add(implicit_argument); |
2714 | 2615 |
2715 // 'this' parameter must not be accessible to the other super call arguments. | 2616 // 'this' parameter must not be accessible to the other super call arguments. |
2716 receiver->set_invisible(true); | 2617 receiver->set_invisible(true); |
2717 ParseActualParameters(arguments, kAllowConst); | 2618 ParseActualParameters(arguments, kAllowConst); |
2718 receiver->set_invisible(false); | 2619 receiver->set_invisible(false); |
2719 | 2620 |
2720 // Resolve the constructor. | 2621 // Resolve the constructor. |
2721 const Function& super_ctor = Function::ZoneHandle(Z, | 2622 const Function& super_ctor = |
2722 super_class.LookupConstructor(ctor_name)); | 2623 Function::ZoneHandle(Z, super_class.LookupConstructor(ctor_name)); |
2723 if (super_ctor.IsNull()) { | 2624 if (super_ctor.IsNull()) { |
2724 ReportError(supercall_pos, | 2625 ReportError(supercall_pos, "super class constructor '%s' not found", |
2725 "super class constructor '%s' not found", | |
2726 ctor_name.ToCString()); | 2626 ctor_name.ToCString()); |
2727 } | 2627 } |
2728 if (current_function().is_const() && !super_ctor.is_const()) { | 2628 if (current_function().is_const() && !super_ctor.is_const()) { |
2729 ReportError(supercall_pos, "super constructor must be const"); | 2629 ReportError(supercall_pos, "super constructor must be const"); |
2730 } | 2630 } |
2731 String& error_message = String::Handle(Z); | 2631 String& error_message = String::Handle(Z); |
2732 if (!super_ctor.AreValidArguments(arguments->length(), | 2632 if (!super_ctor.AreValidArguments(arguments->length(), arguments->names(), |
2733 arguments->names(), | |
2734 &error_message)) { | 2633 &error_message)) { |
2735 ReportError(supercall_pos, | 2634 ReportError(supercall_pos, |
2736 "invalid arguments passed to super class constructor '%s': %s", | 2635 "invalid arguments passed to super class constructor '%s': %s", |
2737 ctor_name.ToCString(), | 2636 ctor_name.ToCString(), error_message.ToCString()); |
2738 error_message.ToCString()); | |
2739 } | 2637 } |
2740 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2638 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2741 } | 2639 } |
2742 | 2640 |
2743 | 2641 |
2744 AstNode* Parser::ParseInitializer(const Class& cls, | 2642 AstNode* Parser::ParseInitializer(const Class& cls, |
2745 LocalVariable* receiver, | 2643 LocalVariable* receiver, |
2746 GrowableArray<Field*>* initialized_fields) { | 2644 GrowableArray<Field*>* initialized_fields) { |
2747 TRACE_PARSER("ParseInitializer"); | 2645 TRACE_PARSER("ParseInitializer"); |
2748 const TokenPosition field_pos = TokenPos(); | 2646 const TokenPosition field_pos = TokenPos(); |
(...skipping 27 matching lines...) Expand all Loading... |
2776 // is evaluated and canonicalized. See issue 27164. | 2674 // is evaluated and canonicalized. See issue 27164. |
2777 init_expr = FoldConstExpr(expr_pos, init_expr); | 2675 init_expr = FoldConstExpr(expr_pos, init_expr); |
2778 } | 2676 } |
2779 } | 2677 } |
2780 Field& field = Field::ZoneHandle(Z, cls.LookupInstanceField(field_name)); | 2678 Field& field = Field::ZoneHandle(Z, cls.LookupInstanceField(field_name)); |
2781 if (field.IsNull()) { | 2679 if (field.IsNull()) { |
2782 ReportError(field_pos, "unresolved reference to instance field '%s'", | 2680 ReportError(field_pos, "unresolved reference to instance field '%s'", |
2783 field_name.ToCString()); | 2681 field_name.ToCString()); |
2784 } | 2682 } |
2785 EnsureExpressionTemp(); | 2683 EnsureExpressionTemp(); |
2786 AstNode* instance = new(Z) LoadLocalNode(field_pos, receiver); | 2684 AstNode* instance = new (Z) LoadLocalNode(field_pos, receiver); |
2787 AstNode* initializer = CheckDuplicateFieldInit(field_pos, | 2685 AstNode* initializer = CheckDuplicateFieldInit(field_pos, initialized_fields, |
2788 initialized_fields, instance, &field, init_expr); | 2686 instance, &field, init_expr); |
2789 if (initializer == NULL) { | 2687 if (initializer == NULL) { |
2790 initializer = | 2688 initializer = |
2791 new(Z) StoreInstanceFieldNode(field_pos, instance, field, init_expr, | 2689 new (Z) StoreInstanceFieldNode(field_pos, instance, field, init_expr, |
2792 /* is_initializer = */ true); | 2690 /* is_initializer = */ true); |
2793 } | 2691 } |
2794 return initializer; | 2692 return initializer; |
2795 } | 2693 } |
2796 | 2694 |
2797 | 2695 |
2798 void Parser::CheckFieldsInitialized(const Class& cls) { | 2696 void Parser::CheckFieldsInitialized(const Class& cls) { |
2799 const Array& fields = Array::Handle(Z, cls.fields()); | 2697 const Array& fields = Array::Handle(Z, cls.fields()); |
2800 Field& field = Field::Handle(Z); | 2698 Field& field = Field::Handle(Z); |
2801 SequenceNode* initializers = current_block_->statements; | 2699 SequenceNode* initializers = current_block_->statements; |
2802 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 2700 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2853 if (init_expr->EvalConstExpr() != NULL) { | 2751 if (init_expr->EvalConstExpr() != NULL) { |
2854 init_expr = FoldConstExpr(expr_pos, init_expr); | 2752 init_expr = FoldConstExpr(expr_pos, init_expr); |
2855 } | 2753 } |
2856 } | 2754 } |
2857 set_library(saved_library); | 2755 set_library(saved_library); |
2858 SetScript(saved_script, saved_token_pos); | 2756 SetScript(saved_script, saved_token_pos); |
2859 return init_expr; | 2757 return init_expr; |
2860 } | 2758 } |
2861 | 2759 |
2862 | 2760 |
2863 void Parser::ParseInitializedInstanceFields(const Class& cls, | 2761 void Parser::ParseInitializedInstanceFields( |
2864 LocalVariable* receiver, | 2762 const Class& cls, |
2865 GrowableArray<Field*>* initialized_fields) { | 2763 LocalVariable* receiver, |
| 2764 GrowableArray<Field*>* initialized_fields) { |
2866 TRACE_PARSER("ParseInitializedInstanceFields"); | 2765 TRACE_PARSER("ParseInitializedInstanceFields"); |
2867 const Array& fields = Array::Handle(Z, cls.fields()); | 2766 const Array& fields = Array::Handle(Z, cls.fields()); |
2868 Field& f = Field::Handle(Z); | 2767 Field& f = Field::Handle(Z); |
2869 const TokenPosition saved_pos = TokenPos(); | 2768 const TokenPosition saved_pos = TokenPos(); |
2870 for (int i = 0; i < fields.Length(); i++) { | 2769 for (int i = 0; i < fields.Length(); i++) { |
2871 f ^= fields.At(i); | 2770 f ^= fields.At(i); |
2872 if (!f.is_static() && f.has_initializer()) { | 2771 if (!f.is_static() && f.has_initializer()) { |
2873 Field& field = Field::ZoneHandle(Z); | 2772 Field& field = Field::ZoneHandle(Z); |
2874 field ^= fields.At(i); | 2773 field ^= fields.At(i); |
2875 if (field.is_final()) { | 2774 if (field.is_final()) { |
(...skipping 18 matching lines...) Expand all Loading... |
2894 TokenPosition expr_pos = TokenPos(); | 2793 TokenPosition expr_pos = TokenPos(); |
2895 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2794 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2896 if (init_expr->EvalConstExpr() != NULL) { | 2795 if (init_expr->EvalConstExpr() != NULL) { |
2897 init_expr = FoldConstExpr(expr_pos, init_expr); | 2796 init_expr = FoldConstExpr(expr_pos, init_expr); |
2898 } | 2797 } |
2899 } | 2798 } |
2900 } | 2799 } |
2901 ASSERT(init_expr != NULL); | 2800 ASSERT(init_expr != NULL); |
2902 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); | 2801 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); |
2903 EnsureExpressionTemp(); | 2802 EnsureExpressionTemp(); |
2904 AstNode* field_init = | 2803 AstNode* field_init = new StoreInstanceFieldNode( |
2905 new StoreInstanceFieldNode(field.token_pos(), | 2804 field.token_pos(), instance, field, init_expr, |
2906 instance, | 2805 /* is_initializer = */ true); |
2907 field, | |
2908 init_expr, | |
2909 /* is_initializer = */ true); | |
2910 current_block_->statements->Add(field_init); | 2806 current_block_->statements->Add(field_init); |
2911 } | 2807 } |
2912 } | 2808 } |
2913 initialized_fields->Add(NULL); // End of inline initializers. | 2809 initialized_fields->Add(NULL); // End of inline initializers. |
2914 SetPosition(saved_pos); | 2810 SetPosition(saved_pos); |
2915 } | 2811 } |
2916 | 2812 |
2917 | 2813 |
2918 AstNode* Parser::CheckDuplicateFieldInit( | 2814 AstNode* Parser::CheckDuplicateFieldInit( |
2919 TokenPosition init_pos, | 2815 TokenPosition init_pos, |
(...skipping 24 matching lines...) Expand all Loading... |
2944 ASSERT(field->is_final()); | 2840 ASSERT(field->is_final()); |
2945 | 2841 |
2946 // Build a call to NoSuchMethodError::_throwNew( | 2842 // Build a call to NoSuchMethodError::_throwNew( |
2947 // Object receiver, | 2843 // Object receiver, |
2948 // String memberName, | 2844 // String memberName, |
2949 // int invocation_type, | 2845 // int invocation_type, |
2950 // List arguments, | 2846 // List arguments, |
2951 // List argumentNames, | 2847 // List argumentNames, |
2952 // List existingArgumentNames); | 2848 // List existingArgumentNames); |
2953 | 2849 |
2954 ArgumentListNode* nsm_args = new(Z) ArgumentListNode(init_pos); | 2850 ArgumentListNode* nsm_args = new (Z) ArgumentListNode(init_pos); |
2955 // Object receiver. | 2851 // Object receiver. |
2956 nsm_args->Add(instance); | 2852 nsm_args->Add(instance); |
2957 | 2853 |
2958 // String memberName. | 2854 // String memberName. |
2959 String& setter_name = String::ZoneHandle(field->name()); | 2855 String& setter_name = String::ZoneHandle(field->name()); |
2960 setter_name = Field::SetterSymbol(setter_name); | 2856 setter_name = Field::SetterSymbol(setter_name); |
2961 nsm_args->Add(new(Z) LiteralNode(init_pos, setter_name)); | 2857 nsm_args->Add(new (Z) LiteralNode(init_pos, setter_name)); |
2962 | 2858 |
2963 // Smi invocation_type. | 2859 // Smi invocation_type. |
2964 const int invocation_type = | 2860 const int invocation_type = InvocationMirror::EncodeType( |
2965 InvocationMirror::EncodeType(InvocationMirror::kDynamic, | 2861 InvocationMirror::kDynamic, InvocationMirror::kSetter); |
2966 InvocationMirror::kSetter); | 2862 nsm_args->Add(new (Z) LiteralNode( |
2967 nsm_args->Add(new(Z) LiteralNode( | |
2968 init_pos, Smi::ZoneHandle(Z, Smi::New(invocation_type)))); | 2863 init_pos, Smi::ZoneHandle(Z, Smi::New(invocation_type)))); |
2969 | 2864 |
2970 // List arguments. | 2865 // List arguments. |
2971 GrowableArray<AstNode*> setter_args; | 2866 GrowableArray<AstNode*> setter_args; |
2972 setter_args.Add(init_value); | 2867 setter_args.Add(init_value); |
2973 ArrayNode* setter_args_array = new(Z) ArrayNode( | 2868 ArrayNode* setter_args_array = new (Z) ArrayNode( |
2974 init_pos, | 2869 init_pos, Type::ZoneHandle(Z, Type::ArrayType()), setter_args); |
2975 Type::ZoneHandle(Z, Type::ArrayType()), | |
2976 setter_args); | |
2977 nsm_args->Add(setter_args_array); | 2870 nsm_args->Add(setter_args_array); |
2978 | 2871 |
2979 // List argumentNames. | 2872 // List argumentNames. |
2980 // The missing implicit setter of the field has no argument names. | 2873 // The missing implicit setter of the field has no argument names. |
2981 nsm_args->Add(new(Z) LiteralNode(init_pos, Object::null_array())); | 2874 nsm_args->Add(new (Z) LiteralNode(init_pos, Object::null_array())); |
2982 | 2875 |
2983 // List existingArgumentNames. | 2876 // List existingArgumentNames. |
2984 // There is no setter for the final field, thus there are | 2877 // There is no setter for the final field, thus there are |
2985 // no existing names. | 2878 // no existing names. |
2986 nsm_args->Add(new(Z) LiteralNode(init_pos, Object::null_array())); | 2879 nsm_args->Add(new (Z) LiteralNode(init_pos, Object::null_array())); |
2987 | 2880 |
2988 AstNode* nsm_call = MakeStaticCall( | 2881 AstNode* nsm_call = MakeStaticCall( |
2989 Symbols::NoSuchMethodError(), | 2882 Symbols::NoSuchMethodError(), |
2990 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 2883 Library::PrivateCoreLibName(Symbols::ThrowNew()), nsm_args); |
2991 nsm_args); | |
2992 | 2884 |
2993 LetNode* let = new(Z) LetNode(init_pos); | 2885 LetNode* let = new (Z) LetNode(init_pos); |
2994 let->AddNode(init_value); | 2886 let->AddNode(init_value); |
2995 let->AddNode(nsm_call); | 2887 let->AddNode(nsm_call); |
2996 result = let; | 2888 result = let; |
2997 } | 2889 } |
2998 } | 2890 } |
2999 // The remaining elements in initialized_fields are fields that | 2891 // The remaining elements in initialized_fields are fields that |
3000 // are initialized through initializing formal parameters, or | 2892 // are initialized through initializing formal parameters, or |
3001 // in the constructor's initializer list. If there is a duplicate, | 2893 // in the constructor's initializer list. If there is a duplicate, |
3002 // it is a compile time error. | 2894 // it is a compile time error. |
3003 while (initializer_idx < initialized_fields->length()) { | 2895 while (initializer_idx < initialized_fields->length()) { |
3004 Field* initialized_field = (*initialized_fields)[initializer_idx]; | 2896 Field* initialized_field = (*initialized_fields)[initializer_idx]; |
3005 initializer_idx++; | 2897 initializer_idx++; |
3006 if (initialized_field->raw() == field->raw()) { | 2898 if (initialized_field->raw() == field->raw()) { |
3007 ReportError(init_pos, | 2899 ReportError(init_pos, "duplicate initializer for field %s", |
3008 "duplicate initializer for field %s", | |
3009 String::Handle(Z, field->name()).ToCString()); | 2900 String::Handle(Z, field->name()).ToCString()); |
3010 } | 2901 } |
3011 } | 2902 } |
3012 initialized_fields->Add(field); | 2903 initialized_fields->Add(field); |
3013 return result; | 2904 return result; |
3014 } | 2905 } |
3015 | 2906 |
3016 | 2907 |
3017 void Parser::ParseInitializers(const Class& cls, | 2908 void Parser::ParseInitializers(const Class& cls, |
3018 LocalVariable* receiver, | 2909 LocalVariable* receiver, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3061 // could have side effects that alter the arguments to the super | 2952 // could have side effects that alter the arguments to the super |
3062 // initializer.) E.g: | 2953 // initializer.) E.g: |
3063 // A(x) : super(x), f = x++ { ... } | 2954 // A(x) : super(x), f = x++ { ... } |
3064 // is transformed to: | 2955 // is transformed to: |
3065 // A(x) : temp = x, f = x++, super(temp) { ... } | 2956 // A(x) : temp = x, f = x++, super(temp) { ... } |
3066 if (FLAG_warn_super) { | 2957 if (FLAG_warn_super) { |
3067 ReportWarning("Super initializer not at end"); | 2958 ReportWarning("Super initializer not at end"); |
3068 } | 2959 } |
3069 ASSERT(super_init_index >= 0); | 2960 ASSERT(super_init_index >= 0); |
3070 ArgumentListNode* ctor_args = super_init_call->arguments(); | 2961 ArgumentListNode* ctor_args = super_init_call->arguments(); |
3071 LetNode* saved_args = new(Z) LetNode(super_init_call->token_pos()); | 2962 LetNode* saved_args = new (Z) LetNode(super_init_call->token_pos()); |
3072 // The super initializer call has at least 1 arguments: the | 2963 // The super initializer call has at least 1 arguments: the |
3073 // implicit receiver. | 2964 // implicit receiver. |
3074 ASSERT(ctor_args->length() >= 1); | 2965 ASSERT(ctor_args->length() >= 1); |
3075 for (int i = 1; i < ctor_args->length(); i++) { | 2966 for (int i = 1; i < ctor_args->length(); i++) { |
3076 AstNode* arg = ctor_args->NodeAt(i); | 2967 AstNode* arg = ctor_args->NodeAt(i); |
3077 LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca"); | 2968 LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca"); |
3078 AstNode* save_temp = new(Z) StoreLocalNode(arg->token_pos(), temp, arg); | 2969 AstNode* save_temp = new (Z) StoreLocalNode(arg->token_pos(), temp, arg); |
3079 saved_args->AddNode(save_temp); | 2970 saved_args->AddNode(save_temp); |
3080 ctor_args->SetNodeAt(i, new(Z) LoadLocalNode(arg->token_pos(), temp)); | 2971 ctor_args->SetNodeAt(i, new (Z) LoadLocalNode(arg->token_pos(), temp)); |
3081 } | 2972 } |
3082 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); | 2973 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); |
3083 current_block_->statements->Add(super_init_call); | 2974 current_block_->statements->Add(super_init_call); |
3084 } | 2975 } |
3085 CheckFieldsInitialized(cls); | 2976 CheckFieldsInitialized(cls); |
3086 } | 2977 } |
3087 | 2978 |
3088 | 2979 |
3089 void Parser::ParseConstructorRedirection(const Class& cls, | 2980 void Parser::ParseConstructorRedirection(const Class& cls, |
3090 LocalVariable* receiver) { | 2981 LocalVariable* receiver) { |
(...skipping 15 matching lines...) Expand all Loading... |
3106 | 2997 |
3107 ArgumentListNode* arguments = new ArgumentListNode(call_pos); | 2998 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
3108 // 'this' parameter is the first argument to constructor. | 2999 // 'this' parameter is the first argument to constructor. |
3109 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); | 3000 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); |
3110 arguments->Add(implicit_argument); | 3001 arguments->Add(implicit_argument); |
3111 | 3002 |
3112 receiver->set_invisible(true); | 3003 receiver->set_invisible(true); |
3113 ParseActualParameters(arguments, kAllowConst); | 3004 ParseActualParameters(arguments, kAllowConst); |
3114 receiver->set_invisible(false); | 3005 receiver->set_invisible(false); |
3115 // Resolve the constructor. | 3006 // Resolve the constructor. |
3116 const Function& redirect_ctor = Function::ZoneHandle(Z, | 3007 const Function& redirect_ctor = |
3117 cls.LookupConstructor(ctor_name)); | 3008 Function::ZoneHandle(Z, cls.LookupConstructor(ctor_name)); |
3118 if (redirect_ctor.IsNull()) { | 3009 if (redirect_ctor.IsNull()) { |
3119 ReportError(call_pos, "constructor '%s' not found", | 3010 ReportError(call_pos, "constructor '%s' not found", |
3120 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString()); | 3011 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString()); |
3121 } | 3012 } |
3122 if (current_function().is_const() && !redirect_ctor.is_const()) { | 3013 if (current_function().is_const() && !redirect_ctor.is_const()) { |
3123 ReportError(call_pos, | 3014 ReportError(call_pos, "redirection constructor '%s' must be const", |
3124 "redirection constructor '%s' must be const", | 3015 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString()); |
3125 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString()); | |
3126 } | 3016 } |
3127 String& error_message = String::Handle(Z); | 3017 String& error_message = String::Handle(Z); |
3128 if (!redirect_ctor.AreValidArguments(arguments->length(), | 3018 if (!redirect_ctor.AreValidArguments(arguments->length(), arguments->names(), |
3129 arguments->names(), | |
3130 &error_message)) { | 3019 &error_message)) { |
3131 ReportError(call_pos, | 3020 ReportError(call_pos, "invalid arguments passed to constructor '%s': %s", |
3132 "invalid arguments passed to constructor '%s': %s", | |
3133 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString(), | 3021 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString(), |
3134 error_message.ToCString()); | 3022 error_message.ToCString()); |
3135 } | 3023 } |
3136 current_block_->statements->Add( | 3024 current_block_->statements->Add( |
3137 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 3025 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
3138 } | 3026 } |
3139 | 3027 |
3140 | 3028 |
3141 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 3029 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
3142 ASSERT(func.IsGenerativeConstructor()); | 3030 ASSERT(func.IsGenerativeConstructor()); |
3143 ASSERT(func.Owner() == current_class().raw()); | 3031 ASSERT(func.Owner() == current_class().raw()); |
3144 const TokenPosition ctor_pos = TokenPos(); | 3032 const TokenPosition ctor_pos = TokenPos(); |
3145 OpenFunctionBlock(func); | 3033 OpenFunctionBlock(func); |
3146 | 3034 |
3147 LocalVariable* receiver = new LocalVariable( | 3035 LocalVariable* receiver = |
3148 TokenPosition::kNoSource, | 3036 new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
3149 TokenPosition::kNoSource, | 3037 Symbols::This(), *ReceiverType(current_class())); |
3150 Symbols::This(), | |
3151 *ReceiverType(current_class())); | |
3152 current_block_->scope->InsertParameterAt(0, receiver); | 3038 current_block_->scope->InsertParameterAt(0, receiver); |
3153 | 3039 |
3154 // Parse expressions of instance fields that have an explicit | 3040 // Parse expressions of instance fields that have an explicit |
3155 // initializer expression. | 3041 // initializer expression. |
3156 // The receiver must not be visible to field initializer expressions. | 3042 // The receiver must not be visible to field initializer expressions. |
3157 receiver->set_invisible(true); | 3043 receiver->set_invisible(true); |
3158 GrowableArray<Field*> initialized_fields; | 3044 GrowableArray<Field*> initialized_fields; |
3159 ParseInitializedInstanceFields( | 3045 ParseInitializedInstanceFields(current_class(), receiver, |
3160 current_class(), receiver, &initialized_fields); | 3046 &initialized_fields); |
3161 receiver->set_invisible(false); | 3047 receiver->set_invisible(false); |
3162 | 3048 |
3163 // If the class of this implicit constructor is a mixin application alias, | 3049 // If the class of this implicit constructor is a mixin application alias, |
3164 // it is a forwarding constructor of the aliased mixin application class. | 3050 // it is a forwarding constructor of the aliased mixin application class. |
3165 // If the class of this implicit constructor is a mixin application class, | 3051 // If the class of this implicit constructor is a mixin application class, |
3166 // it is a forwarding constructor of the mixin. The forwarding | 3052 // it is a forwarding constructor of the mixin. The forwarding |
3167 // constructor initializes the instance fields that have initializer | 3053 // constructor initializes the instance fields that have initializer |
3168 // expressions and then calls the respective super constructor with | 3054 // expressions and then calls the respective super constructor with |
3169 // the same name and number of parameters. | 3055 // the same name and number of parameters. |
3170 ArgumentListNode* forwarding_args = NULL; | 3056 ArgumentListNode* forwarding_args = NULL; |
(...skipping 15 matching lines...) Expand all Loading... |
3186 "to class '%s' that redirects to the constructor with " | 3072 "to class '%s' that redirects to the constructor with " |
3187 "optional parameters and invoke it via super from a " | 3073 "optional parameters and invoke it via super from a " |
3188 "constructor of the class extending the mixin application", | 3074 "constructor of the class extending the mixin application", |
3189 String::Handle(Z, super_class.Name()).ToCString()); | 3075 String::Handle(Z, super_class.Name()).ToCString()); |
3190 } | 3076 } |
3191 | 3077 |
3192 // Prepare user-defined arguments to be forwarded to super call. | 3078 // Prepare user-defined arguments to be forwarded to super call. |
3193 // The first user-defined argument is at position 1. | 3079 // The first user-defined argument is at position 1. |
3194 forwarding_args = new ArgumentListNode(ST(ctor_pos)); | 3080 forwarding_args = new ArgumentListNode(ST(ctor_pos)); |
3195 for (int i = 1; i < func.NumParameters(); i++) { | 3081 for (int i = 1; i < func.NumParameters(); i++) { |
3196 LocalVariable* param = new LocalVariable( | 3082 LocalVariable* param = |
3197 TokenPosition::kNoSource, | 3083 new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
3198 TokenPosition::kNoSource, | 3084 String::ZoneHandle(Z, func.ParameterNameAt(i)), |
3199 String::ZoneHandle(Z, func.ParameterNameAt(i)), | 3085 Object::dynamic_type()); |
3200 Object::dynamic_type()); | |
3201 current_block_->scope->InsertParameterAt(i, param); | 3086 current_block_->scope->InsertParameterAt(i, param); |
3202 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); | 3087 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); |
3203 } | 3088 } |
3204 } | 3089 } |
3205 | 3090 |
3206 AstNode* super_call = GenerateSuperConstructorCall( | 3091 AstNode* super_call = GenerateSuperConstructorCall(current_class(), ctor_pos, |
3207 current_class(), | 3092 receiver, forwarding_args); |
3208 ctor_pos, | |
3209 receiver, | |
3210 forwarding_args); | |
3211 if (super_call != NULL) { | 3093 if (super_call != NULL) { |
3212 current_block_->statements->Add(super_call); | 3094 current_block_->statements->Add(super_call); |
3213 } | 3095 } |
3214 CheckFieldsInitialized(current_class()); | 3096 CheckFieldsInitialized(current_class()); |
3215 | 3097 |
3216 // Empty constructor body. | 3098 // Empty constructor body. |
3217 current_block_->statements->Add(new ReturnNode(ST(ctor_pos))); | 3099 current_block_->statements->Add(new ReturnNode(ST(ctor_pos))); |
3218 SequenceNode* statements = CloseBlock(); | 3100 SequenceNode* statements = CloseBlock(); |
3219 return statements; | 3101 return statements; |
3220 } | 3102 } |
(...skipping 21 matching lines...) Expand all Loading... |
3242 ASSERT(!pending_functions.IsNull()); | 3124 ASSERT(!pending_functions.IsNull()); |
3243 for (int i = 0; i < pending_functions.Length(); i++) { | 3125 for (int i = 0; i < pending_functions.Length(); i++) { |
3244 if (pending_functions.At(i) == current_function().raw()) { | 3126 if (pending_functions.At(i) == current_function().raw()) { |
3245 const String& fname = | 3127 const String& fname = |
3246 String::Handle(Z, current_function().UserVisibleName()); | 3128 String::Handle(Z, current_function().UserVisibleName()); |
3247 if (FLAG_trace_service) { | 3129 if (FLAG_trace_service) { |
3248 const char* pending_function_dump = | 3130 const char* pending_function_dump = |
3249 DumpPendingFunctions(Z, pending_functions); | 3131 DumpPendingFunctions(Z, pending_functions); |
3250 ASSERT(pending_function_dump != NULL); | 3132 ASSERT(pending_function_dump != NULL); |
3251 ReportError("circular dependency for function %s\n%s", | 3133 ReportError("circular dependency for function %s\n%s", |
3252 fname.ToCString(), | 3134 fname.ToCString(), pending_function_dump); |
3253 pending_function_dump); | |
3254 } else { | 3135 } else { |
3255 ReportError("circular dependency for function %s", fname.ToCString()); | 3136 ReportError("circular dependency for function %s", fname.ToCString()); |
3256 } | 3137 } |
3257 } | 3138 } |
3258 } | 3139 } |
3259 ASSERT(!unregister_pending_function_); | 3140 ASSERT(!unregister_pending_function_); |
3260 pending_functions.Add(current_function(), Heap::kOld); | 3141 pending_functions.Add(current_function(), Heap::kOld); |
3261 unregister_pending_function_ = true; | 3142 unregister_pending_function_ = true; |
3262 } | 3143 } |
3263 | 3144 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3302 | 3183 |
3303 SetupDefaultsForOptionalParams(params); | 3184 SetupDefaultsForOptionalParams(params); |
3304 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 3185 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
3305 ASSERT(func.NumParameters() == params.parameters->length()); | 3186 ASSERT(func.NumParameters() == params.parameters->length()); |
3306 | 3187 |
3307 // Now populate function scope with the formal parameters. | 3188 // Now populate function scope with the formal parameters. |
3308 AddFormalParamsToScope(¶ms, current_block_->scope); | 3189 AddFormalParamsToScope(¶ms, current_block_->scope); |
3309 | 3190 |
3310 const bool is_redirecting_constructor = | 3191 const bool is_redirecting_constructor = |
3311 (CurrentToken() == Token::kCOLON) && | 3192 (CurrentToken() == Token::kCOLON) && |
3312 ((LookaheadToken(1) == Token::kTHIS) && | 3193 ((LookaheadToken(1) == Token::kTHIS) && |
3313 ((LookaheadToken(2) == Token::kLPAREN) || | 3194 ((LookaheadToken(2) == Token::kLPAREN) || |
3314 ((LookaheadToken(2) == Token::kPERIOD) && | 3195 ((LookaheadToken(2) == Token::kPERIOD) && |
3315 (LookaheadToken(4) == Token::kLPAREN)))); | 3196 (LookaheadToken(4) == Token::kLPAREN)))); |
3316 | 3197 |
3317 GrowableArray<Field*> initialized_fields; | 3198 GrowableArray<Field*> initialized_fields; |
3318 LocalVariable* receiver = (*params.parameters)[0].var; | 3199 LocalVariable* receiver = (*params.parameters)[0].var; |
3319 OpenBlock(); | 3200 OpenBlock(); |
3320 | 3201 |
3321 // If this is not a redirecting constructor, initialize | 3202 // If this is not a redirecting constructor, initialize |
3322 // instance fields that have an explicit initializer expression. | 3203 // instance fields that have an explicit initializer expression. |
3323 if (!is_redirecting_constructor) { | 3204 if (!is_redirecting_constructor) { |
3324 // The formal parameter names must not be visible to the instance | 3205 // The formal parameter names must not be visible to the instance |
3325 // field initializer expressions, yet the parameters must be added to | 3206 // field initializer expressions, yet the parameters must be added to |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3363 } | 3244 } |
3364 | 3245 |
3365 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); | 3246 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); |
3366 // Initializing formals cannot be used in the explicit initializer | 3247 // Initializing formals cannot be used in the explicit initializer |
3367 // list, nor can they be used in the constructor body. | 3248 // list, nor can they be used in the constructor body. |
3368 // Thus, they are set to be invisible when added to the scope. | 3249 // Thus, they are set to be invisible when added to the scope. |
3369 LocalVariable* p = param.var; | 3250 LocalVariable* p = param.var; |
3370 ASSERT(p != NULL); | 3251 ASSERT(p != NULL); |
3371 AstNode* value = new LoadLocalNode(param.name_pos, p); | 3252 AstNode* value = new LoadLocalNode(param.name_pos, p); |
3372 EnsureExpressionTemp(); | 3253 EnsureExpressionTemp(); |
3373 AstNode* initializer = | 3254 AstNode* initializer = CheckDuplicateFieldInit( |
3374 CheckDuplicateFieldInit(param.name_pos, | 3255 param.name_pos, &initialized_fields, instance, &field, value); |
3375 &initialized_fields, | |
3376 instance, | |
3377 &field, | |
3378 value); | |
3379 if (initializer == NULL) { | 3256 if (initializer == NULL) { |
3380 initializer = new(Z) StoreInstanceFieldNode( | 3257 initializer = new (Z) |
3381 param.name_pos, instance, field, value, | 3258 StoreInstanceFieldNode(param.name_pos, instance, field, value, |
3382 /* is_initializer = */ true); | 3259 /* is_initializer = */ true); |
3383 } | 3260 } |
3384 current_block_->statements->Add(initializer); | 3261 current_block_->statements->Add(initializer); |
3385 } | 3262 } |
3386 } | 3263 } |
3387 } | 3264 } |
3388 | 3265 |
3389 if (is_redirecting_constructor) { | 3266 if (is_redirecting_constructor) { |
3390 ParseConstructorRedirection(cls, receiver); | 3267 ParseConstructorRedirection(cls, receiver); |
3391 } else { | 3268 } else { |
3392 ParseInitializers(cls, receiver, &initialized_fields); | 3269 ParseInitializers(cls, receiver, &initialized_fields); |
(...skipping 17 matching lines...) Expand all Loading... |
3410 } else if (CurrentToken() == Token::kARROW) { | 3287 } else if (CurrentToken() == Token::kARROW) { |
3411 ReportError("constructors may not return a value"); | 3288 ReportError("constructors may not return a value"); |
3412 } else if (IsSymbol(Symbols::Native())) { | 3289 } else if (IsSymbol(Symbols::Native())) { |
3413 ReportError("native constructors not supported"); | 3290 ReportError("native constructors not supported"); |
3414 } else if (CurrentToken() == Token::kSEMICOLON) { | 3291 } else if (CurrentToken() == Token::kSEMICOLON) { |
3415 // Some constructors have no function body. | 3292 // Some constructors have no function body. |
3416 ConsumeToken(); | 3293 ConsumeToken(); |
3417 if (func.is_external()) { | 3294 if (func.is_external()) { |
3418 // Body of an external method contains a single throw. | 3295 // Body of an external method contains a single throw. |
3419 const String& function_name = String::ZoneHandle(func.name()); | 3296 const String& function_name = String::ZoneHandle(func.name()); |
3420 current_block_->statements->Add( | 3297 current_block_->statements->Add(ThrowNoSuchMethodError( |
3421 ThrowNoSuchMethodError(TokenPos(), | 3298 TokenPos(), cls, function_name, |
3422 cls, | 3299 NULL, // No arguments. |
3423 function_name, | 3300 InvocationMirror::kStatic, InvocationMirror::kMethod, |
3424 NULL, // No arguments. | 3301 NULL)); // No existing function. |
3425 InvocationMirror::kStatic, | |
3426 InvocationMirror::kMethod, | |
3427 NULL)); // No existing function. | |
3428 } | 3302 } |
3429 } else { | 3303 } else { |
3430 UnexpectedToken(); | 3304 UnexpectedToken(); |
3431 } | 3305 } |
3432 | 3306 |
3433 SequenceNode* ctor_block = CloseBlock(); | 3307 SequenceNode* ctor_block = CloseBlock(); |
3434 if (ctor_block->length() > 0) { | 3308 if (ctor_block->length() > 0) { |
3435 current_block_->statements->Add(ctor_block); | 3309 current_block_->statements->Add(ctor_block); |
3436 } | 3310 } |
3437 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 3311 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
(...skipping 25 matching lines...) Expand all Loading... |
3463 | 3337 |
3464 ASSERT(!func.IsGenerativeConstructor()); | 3338 ASSERT(!func.IsGenerativeConstructor()); |
3465 OpenFunctionBlock(func); // Build local scope for function. | 3339 OpenFunctionBlock(func); // Build local scope for function. |
3466 | 3340 |
3467 ParamList params; | 3341 ParamList params; |
3468 // An instance closure function may capture and access the receiver, but via | 3342 // An instance closure function may capture and access the receiver, but via |
3469 // the context and not via the first formal parameter. | 3343 // the context and not via the first formal parameter. |
3470 if (func.IsClosureFunction()) { | 3344 if (func.IsClosureFunction()) { |
3471 // The first parameter of a closure function is the closure object. | 3345 // The first parameter of a closure function is the closure object. |
3472 ASSERT(!func.is_const()); // Closure functions cannot be const. | 3346 ASSERT(!func.is_const()); // Closure functions cannot be const. |
3473 params.AddFinalParameter( | 3347 params.AddFinalParameter(TokenPos(), &Symbols::ClosureParameter(), |
3474 TokenPos(), | 3348 &Object::dynamic_type()); |
3475 &Symbols::ClosureParameter(), | |
3476 &Object::dynamic_type()); | |
3477 } else if (!func.is_static()) { | 3349 } else if (!func.is_static()) { |
3478 // Static functions do not have a receiver. | 3350 // Static functions do not have a receiver. |
3479 ASSERT(current_class().raw() == func.Owner()); | 3351 ASSERT(current_class().raw() == func.Owner()); |
3480 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 3352 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
3481 } else if (func.IsFactory()) { | 3353 } else if (func.IsFactory()) { |
3482 // The first parameter of a factory is the TypeArguments vector of | 3354 // The first parameter of a factory is the TypeArguments vector of |
3483 // the type of the instance to be allocated. | 3355 // the type of the instance to be allocated. |
3484 params.AddFinalParameter( | 3356 params.AddFinalParameter(TokenPos(), &Symbols::TypeArgumentsParameter(), |
3485 TokenPos(), | 3357 &Object::dynamic_type()); |
3486 &Symbols::TypeArgumentsParameter(), | |
3487 &Object::dynamic_type()); | |
3488 } | 3358 } |
3489 // Expect the parameter list unless this is a getter function, or the | 3359 // Expect the parameter list unless this is a getter function, or the |
3490 // body closure of an async or generator getter function. | 3360 // body closure of an async or generator getter function. |
3491 ASSERT((CurrentToken() == Token::kLPAREN) || | 3361 ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction() || |
3492 func.IsGetterFunction() || | |
3493 (func.is_generated_body() && | 3362 (func.is_generated_body() && |
3494 Function::Handle(func.parent_function()).IsGetterFunction())); | 3363 Function::Handle(func.parent_function()).IsGetterFunction())); |
3495 const bool allow_explicit_default_values = true; | 3364 const bool allow_explicit_default_values = true; |
3496 if (func.IsGetterFunction()) { | 3365 if (func.IsGetterFunction()) { |
3497 // Populate function scope with the formal parameters. Since in this case | 3366 // Populate function scope with the formal parameters. Since in this case |
3498 // we are compiling a getter this will at most populate the receiver. | 3367 // we are compiling a getter this will at most populate the receiver. |
3499 AddFormalParamsToScope(¶ms, current_block_->scope); | 3368 AddFormalParamsToScope(¶ms, current_block_->scope); |
3500 } else if (func.IsAsyncClosure()) { | 3369 } else if (func.IsAsyncClosure()) { |
3501 AddAsyncClosureParameters(¶ms); | 3370 AddAsyncClosureParameters(¶ms); |
3502 SetupDefaultsForOptionalParams(params); | 3371 SetupDefaultsForOptionalParams(params); |
3503 AddFormalParamsToScope(¶ms, current_block_->scope); | 3372 AddFormalParamsToScope(¶ms, current_block_->scope); |
3504 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 3373 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3542 if (func.parameter_types() == Object::empty_array().raw()) { | 3411 if (func.parameter_types() == Object::empty_array().raw()) { |
3543 AddFormalParamsToFunction(¶ms, func); | 3412 AddFormalParamsToFunction(¶ms, func); |
3544 } | 3413 } |
3545 SetupDefaultsForOptionalParams(params); | 3414 SetupDefaultsForOptionalParams(params); |
3546 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 3415 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
3547 ASSERT(func.NumParameters() == params.parameters->length()); | 3416 ASSERT(func.NumParameters() == params.parameters->length()); |
3548 | 3417 |
3549 // Populate function scope with the formal parameters. | 3418 // Populate function scope with the formal parameters. |
3550 AddFormalParamsToScope(¶ms, current_block_->scope); | 3419 AddFormalParamsToScope(¶ms, current_block_->scope); |
3551 | 3420 |
3552 if (I->type_checks() && | 3421 if (I->type_checks() && (FunctionLevel() > 0)) { |
3553 (FunctionLevel() > 0)) { | |
3554 // We are parsing, but not compiling, a local function. | 3422 // We are parsing, but not compiling, a local function. |
3555 // The instantiator may be required at run time for generic type checks. | 3423 // The instantiator may be required at run time for generic type checks. |
3556 if (IsInstantiatorRequired()) { | 3424 if (IsInstantiatorRequired()) { |
3557 // Make sure that the receiver of the enclosing instance function | 3425 // Make sure that the receiver of the enclosing instance function |
3558 // (or implicit first parameter of an enclosing factory) is marked as | 3426 // (or implicit first parameter of an enclosing factory) is marked as |
3559 // captured if type checks are enabled, because they may access it to | 3427 // captured if type checks are enabled, because they may access it to |
3560 // instantiate types. | 3428 // instantiate types. |
3561 CaptureInstantiator(); | 3429 CaptureInstantiator(); |
3562 } | 3430 } |
3563 } | 3431 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3613 } | 3481 } |
3614 ParseStatementSequence(); | 3482 ParseStatementSequence(); |
3615 end_token_pos = TokenPos(); | 3483 end_token_pos = TokenPos(); |
3616 ExpectToken(Token::kRBRACE); | 3484 ExpectToken(Token::kRBRACE); |
3617 } else if (CurrentToken() == Token::kARROW) { | 3485 } else if (CurrentToken() == Token::kARROW) { |
3618 if (func.IsGenerator()) { | 3486 if (func.IsGenerator()) { |
3619 ReportError(modifier_pos, | 3487 ReportError(modifier_pos, |
3620 "=> style function may not be sync* or async* generator"); | 3488 "=> style function may not be sync* or async* generator"); |
3621 } | 3489 } |
3622 ConsumeToken(); | 3490 ConsumeToken(); |
3623 if (String::Handle(Z, func.name()).Equals( | 3491 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
3624 Symbols::EqualOperator())) { | |
3625 const Class& owner = Class::Handle(Z, func.Owner()); | 3492 const Class& owner = Class::Handle(Z, func.Owner()); |
3626 if (!owner.IsObjectClass()) { | 3493 if (!owner.IsObjectClass()) { |
3627 AddEqualityNullCheck(); | 3494 AddEqualityNullCheck(); |
3628 } | 3495 } |
3629 } | 3496 } |
3630 const TokenPosition expr_pos = TokenPos(); | 3497 const TokenPosition expr_pos = TokenPos(); |
3631 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 3498 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
3632 ASSERT(expr != NULL); | 3499 ASSERT(expr != NULL); |
3633 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3500 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
3634 end_token_pos = TokenPos(); | 3501 end_token_pos = TokenPos(); |
3635 if (check_semicolon) { | 3502 if (check_semicolon) { |
3636 ExpectSemicolon(); | 3503 ExpectSemicolon(); |
3637 } | 3504 } |
3638 } else if (IsSymbol(Symbols::Native())) { | 3505 } else if (IsSymbol(Symbols::Native())) { |
3639 if (String::Handle(Z, func.name()).Equals( | 3506 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
3640 Symbols::EqualOperator())) { | |
3641 const Class& owner = Class::Handle(Z, func.Owner()); | 3507 const Class& owner = Class::Handle(Z, func.Owner()); |
3642 if (!owner.IsObjectClass()) { | 3508 if (!owner.IsObjectClass()) { |
3643 AddEqualityNullCheck(); | 3509 AddEqualityNullCheck(); |
3644 } | 3510 } |
3645 } | 3511 } |
3646 ParseNativeFunctionBlock(¶ms, func); | 3512 ParseNativeFunctionBlock(¶ms, func); |
3647 end_token_pos = TokenPos(); | 3513 end_token_pos = TokenPos(); |
3648 ExpectSemicolon(); | 3514 ExpectSemicolon(); |
3649 } else if (func.is_external()) { | 3515 } else if (func.is_external()) { |
3650 // Body of an external method contains a single throw. | 3516 // Body of an external method contains a single throw. |
3651 const String& function_name = String::ZoneHandle(Z, func.name()); | 3517 const String& function_name = String::ZoneHandle(Z, func.name()); |
3652 current_block_->statements->Add( | 3518 current_block_->statements->Add(ThrowNoSuchMethodError( |
3653 ThrowNoSuchMethodError(TokenPos(), | 3519 TokenPos(), Class::Handle(func.Owner()), function_name, |
3654 Class::Handle(func.Owner()), | 3520 NULL, // Ignore arguments. |
3655 function_name, | 3521 func.is_static() ? InvocationMirror::kStatic |
3656 NULL, // Ignore arguments. | 3522 : InvocationMirror::kDynamic, |
3657 func.is_static() ? | 3523 InvocationMirror::kMethod, |
3658 InvocationMirror::kStatic : | 3524 &func)); // Unpatched external function. |
3659 InvocationMirror::kDynamic, | |
3660 InvocationMirror::kMethod, | |
3661 &func)); // Unpatched external function. | |
3662 end_token_pos = TokenPos(); | 3525 end_token_pos = TokenPos(); |
3663 } else { | 3526 } else { |
3664 UnexpectedToken(); | 3527 UnexpectedToken(); |
3665 } | 3528 } |
3666 | 3529 |
3667 ASSERT(func.end_token_pos() == func.token_pos() || | 3530 ASSERT(func.end_token_pos() == func.token_pos() || |
3668 func.end_token_pos() == end_token_pos); | 3531 func.end_token_pos() == end_token_pos); |
3669 func.set_end_token_pos(end_token_pos); | 3532 func.set_end_token_pos(end_token_pos); |
3670 SequenceNode* body = CloseBlock(); | 3533 SequenceNode* body = CloseBlock(); |
3671 if (func.IsAsyncFunction()) { | 3534 if (func.IsAsyncFunction()) { |
(...skipping 14 matching lines...) Expand all Loading... |
3686 } | 3549 } |
3687 EnsureHasReturnStatement(body, end_token_pos); | 3550 EnsureHasReturnStatement(body, end_token_pos); |
3688 current_block_->statements->Add(body); | 3551 current_block_->statements->Add(body); |
3689 last_used_try_index_ = saved_try_index; | 3552 last_used_try_index_ = saved_try_index; |
3690 async_temp_scope_ = saved_async_temp_scope; | 3553 async_temp_scope_ = saved_async_temp_scope; |
3691 return CloseBlock(); | 3554 return CloseBlock(); |
3692 } | 3555 } |
3693 | 3556 |
3694 | 3557 |
3695 void Parser::AddEqualityNullCheck() { | 3558 void Parser::AddEqualityNullCheck() { |
3696 AstNode* argument = | 3559 AstNode* argument = new LoadLocalNode( |
3697 new LoadLocalNode(TokenPosition::kNoSource, | 3560 TokenPosition::kNoSource, current_block_->scope->parent()->VariableAt(1)); |
3698 current_block_->scope->parent()->VariableAt(1)); | |
3699 LiteralNode* null_operand = | 3561 LiteralNode* null_operand = |
3700 new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z)); | 3562 new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z)); |
3701 ComparisonNode* check_arg = | 3563 ComparisonNode* check_arg = new ComparisonNode( |
3702 new ComparisonNode(TokenPosition::kNoSource, | 3564 TokenPosition::kNoSource, Token::kEQ_STRICT, argument, null_operand); |
3703 Token::kEQ_STRICT, | |
3704 argument, | |
3705 null_operand); | |
3706 ComparisonNode* result = | 3565 ComparisonNode* result = |
3707 new ComparisonNode(TokenPosition::kNoSource, | 3566 new ComparisonNode(TokenPosition::kNoSource, Token::kEQ_STRICT, |
3708 Token::kEQ_STRICT, | 3567 LoadReceiver(TokenPosition::kNoSource), null_operand); |
3709 LoadReceiver(TokenPosition::kNoSource), | 3568 SequenceNode* arg_is_null = |
3710 null_operand); | 3569 new SequenceNode(TokenPosition::kNoSource, current_block_->scope); |
3711 SequenceNode* arg_is_null = new SequenceNode(TokenPosition::kNoSource, | |
3712 current_block_->scope); | |
3713 arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result)); | 3570 arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result)); |
3714 IfNode* if_arg_null = new IfNode(TokenPosition::kNoSource, | 3571 IfNode* if_arg_null = |
3715 check_arg, | 3572 new IfNode(TokenPosition::kNoSource, check_arg, arg_is_null, NULL); |
3716 arg_is_null, | |
3717 NULL); | |
3718 current_block_->statements->Add(if_arg_null); | 3573 current_block_->statements->Add(if_arg_null); |
3719 } | 3574 } |
3720 | 3575 |
3721 | 3576 |
3722 void Parser::SkipIf(Token::Kind token) { | 3577 void Parser::SkipIf(Token::Kind token) { |
3723 if (CurrentToken() == token) { | 3578 if (CurrentToken() == token) { |
3724 ConsumeToken(); | 3579 ConsumeToken(); |
3725 } | 3580 } |
3726 } | 3581 } |
3727 | 3582 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3800 // We have a name that is not shadowed, followed by a period or #. | 3655 // We have a name that is not shadowed, followed by a period or #. |
3801 // Consume the identifier, let the caller consume the . or #. | 3656 // Consume the identifier, let the caller consume the . or #. |
3802 ConsumeToken(); | 3657 ConsumeToken(); |
3803 return prefix.raw(); | 3658 return prefix.raw(); |
3804 } | 3659 } |
3805 | 3660 |
3806 | 3661 |
3807 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3662 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
3808 TRACE_PARSER("ParseMethodOrConstructor"); | 3663 TRACE_PARSER("ParseMethodOrConstructor"); |
3809 // We are at the beginning of the formal parameters list. | 3664 // We are at the beginning of the formal parameters list. |
3810 ASSERT(CurrentToken() == Token::kLPAREN || | 3665 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT || |
3811 CurrentToken() == Token::kLT || | |
3812 method->IsGetter()); | 3666 method->IsGetter()); |
3813 ASSERT(method->type != NULL); // May still be unresolved. | 3667 ASSERT(method->type != NULL); // May still be unresolved. |
3814 ASSERT(current_member_ == method); | 3668 ASSERT(current_member_ == method); |
3815 | 3669 |
3816 if (method->has_var) { | 3670 if (method->has_var) { |
3817 ReportError(method->name_pos, "keyword var not allowed for methods"); | 3671 ReportError(method->name_pos, "keyword var not allowed for methods"); |
3818 } | 3672 } |
3819 if (method->has_final) { | 3673 if (method->has_final) { |
3820 ReportError(method->name_pos, "'final' not allowed for methods"); | 3674 ReportError(method->name_pos, "'final' not allowed for methods"); |
3821 } | 3675 } |
3822 if (method->has_abstract && method->has_static) { | 3676 if (method->has_abstract && method->has_static) { |
3823 ReportError(method->name_pos, | 3677 ReportError(method->name_pos, "static method '%s' cannot be abstract", |
3824 "static method '%s' cannot be abstract", | |
3825 method->name->ToCString()); | 3678 method->name->ToCString()); |
3826 } | 3679 } |
3827 if (method->has_const && !method->IsFactoryOrConstructor()) { | 3680 if (method->has_const && !method->IsFactoryOrConstructor()) { |
3828 ReportError(method->name_pos, "'const' not allowed for methods"); | 3681 ReportError(method->name_pos, "'const' not allowed for methods"); |
3829 } | 3682 } |
3830 if (method->has_abstract && method->IsFactoryOrConstructor()) { | 3683 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
3831 ReportError(method->name_pos, "constructor cannot be abstract"); | 3684 ReportError(method->name_pos, "constructor cannot be abstract"); |
3832 } | 3685 } |
3833 if (method->has_const && method->IsConstructor()) { | 3686 if (method->has_const && method->IsConstructor()) { |
3834 current_class().set_is_const(); | 3687 current_class().set_is_const(); |
3835 } | 3688 } |
3836 | 3689 |
3837 Function& func = Function::Handle(Z, | 3690 Function& func = Function::Handle( |
| 3691 Z, |
3838 Function::New(*method->name, // May change. | 3692 Function::New(*method->name, // May change. |
3839 method->kind, | 3693 method->kind, method->has_static, method->has_const, |
3840 method->has_static, | |
3841 method->has_const, | |
3842 method->has_abstract, // May change. | 3694 method->has_abstract, // May change. |
3843 method->has_external, | 3695 method->has_external, |
3844 method->has_native, // May change. | 3696 method->has_native, // May change. |
3845 current_class(), | 3697 current_class(), method->decl_begin_pos)); |
3846 method->decl_begin_pos)); | |
3847 | 3698 |
3848 ASSERT(innermost_function().IsNull()); | 3699 ASSERT(innermost_function().IsNull()); |
3849 innermost_function_ = func.raw(); | 3700 innermost_function_ = func.raw(); |
3850 | 3701 |
3851 if (CurrentToken() == Token::kLT) { | 3702 if (CurrentToken() == Token::kLT) { |
3852 if (!FLAG_generic_method_syntax) { | 3703 if (!FLAG_generic_method_syntax) { |
3853 ReportError("generic type arguments not supported."); | 3704 ReportError("generic type arguments not supported."); |
3854 } | 3705 } |
3855 TokenPosition type_param_pos = TokenPos(); | 3706 TokenPosition type_param_pos = TokenPos(); |
3856 if (method->IsFactoryOrConstructor()) { | 3707 if (method->IsFactoryOrConstructor()) { |
3857 ReportError(method->name_pos, "constructor cannot be generic"); | 3708 ReportError(method->name_pos, "constructor cannot be generic"); |
3858 } | 3709 } |
3859 if (method->IsGetter() || method->IsSetter()) { | 3710 if (method->IsGetter() || method->IsSetter()) { |
3860 ReportError(type_param_pos, "%s cannot be generic", | 3711 ReportError(type_param_pos, "%s cannot be generic", |
3861 method->IsGetter() ? "getter" : "setter"); | 3712 method->IsGetter() ? "getter" : "setter"); |
3862 } | 3713 } |
3863 ParseTypeParameters(false); // Not parameterizing class, but function. | 3714 ParseTypeParameters(false); // Not parameterizing class, but function. |
3864 } | 3715 } |
3865 | 3716 |
3866 // Now that type parameters are declared, the result type can be resolved. | 3717 // Now that type parameters are declared, the result type can be resolved. |
3867 if (!method->type->IsResolved()) { | 3718 if (!method->type->IsResolved()) { |
3868 AbstractType& type = AbstractType::ZoneHandle(Z, method->type->raw()); | 3719 AbstractType& type = AbstractType::ZoneHandle(Z, method->type->raw()); |
3869 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); | 3720 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); |
3870 method->type = &type; | 3721 method->type = &type; |
3871 } | 3722 } |
3872 | 3723 |
3873 // Parse the formal parameters. | 3724 // Parse the formal parameters. |
3874 const bool are_implicitly_final = method->has_const; | 3725 const bool are_implicitly_final = method->has_const; |
3875 const bool allow_explicit_default_values = true; | 3726 const bool allow_explicit_default_values = true; |
3876 const TokenPosition formal_param_pos = TokenPos(); | 3727 const TokenPosition formal_param_pos = TokenPos(); |
3877 method->params.Clear(); | 3728 method->params.Clear(); |
3878 // Static functions do not have a receiver. | 3729 // Static functions do not have a receiver. |
3879 // The first parameter of a factory is the TypeArguments vector of | 3730 // The first parameter of a factory is the TypeArguments vector of |
3880 // the type of the instance to be allocated. | 3731 // the type of the instance to be allocated. |
3881 if (!method->has_static || method->IsConstructor()) { | 3732 if (!method->has_static || method->IsConstructor()) { |
3882 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); | 3733 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); |
3883 } else if (method->IsFactory()) { | 3734 } else if (method->IsFactory()) { |
3884 method->params.AddFinalParameter( | 3735 method->params.AddFinalParameter(formal_param_pos, |
3885 formal_param_pos, | 3736 &Symbols::TypeArgumentsParameter(), |
3886 &Symbols::TypeArgumentsParameter(), | 3737 &Object::dynamic_type()); |
3887 &Object::dynamic_type()); | |
3888 } | 3738 } |
3889 if (are_implicitly_final) { | 3739 if (are_implicitly_final) { |
3890 method->params.SetImplicitlyFinal(); | 3740 method->params.SetImplicitlyFinal(); |
3891 } | 3741 } |
3892 if (!method->IsGetter()) { | 3742 if (!method->IsGetter()) { |
3893 ParseFormalParameterList(allow_explicit_default_values, | 3743 ParseFormalParameterList(allow_explicit_default_values, false, |
3894 false, | |
3895 &method->params); | 3744 &method->params); |
3896 } | 3745 } |
3897 | 3746 |
3898 // Now that we know the parameter list, we can distinguish between the | 3747 // Now that we know the parameter list, we can distinguish between the |
3899 // unary and binary operator -. | 3748 // unary and binary operator -. |
3900 if (method->has_operator) { | 3749 if (method->has_operator) { |
3901 if ((method->operator_token == Token::kSUB) && | 3750 if ((method->operator_token == Token::kSUB) && |
3902 (method->params.num_fixed_parameters == 1)) { | 3751 (method->params.num_fixed_parameters == 1)) { |
3903 // Patch up name for unary operator - so it does not clash with the | 3752 // Patch up name for unary operator - so it does not clash with the |
3904 // name for binary operator -. | 3753 // name for binary operator -. |
3905 method->operator_token = Token::kNEGATE; | 3754 method->operator_token = Token::kNEGATE; |
3906 *method->name = Symbols::Token(Token::kNEGATE).raw(); | 3755 *method->name = Symbols::Token(Token::kNEGATE).raw(); |
3907 } | 3756 } |
3908 CheckOperatorArity(*method); | 3757 CheckOperatorArity(*method); |
3909 } | 3758 } |
3910 | 3759 |
3911 // Mangle the name for getter and setter functions and check function | 3760 // Mangle the name for getter and setter functions and check function |
3912 // arity. | 3761 // arity. |
3913 if (method->IsGetter() || method->IsSetter()) { | 3762 if (method->IsGetter() || method->IsSetter()) { |
3914 int expected_num_parameters = 0; | 3763 int expected_num_parameters = 0; |
3915 if (method->IsGetter()) { | 3764 if (method->IsGetter()) { |
3916 expected_num_parameters = (method->has_static) ? 0 : 1; | 3765 expected_num_parameters = (method->has_static) ? 0 : 1; |
3917 method->dict_name = method->name; | 3766 method->dict_name = method->name; |
3918 method->name = &String::ZoneHandle(Z, Field::GetterSymbol(*method->name)); | 3767 method->name = &String::ZoneHandle(Z, Field::GetterSymbol(*method->name)); |
3919 } else { | 3768 } else { |
3920 ASSERT(method->IsSetter()); | 3769 ASSERT(method->IsSetter()); |
3921 expected_num_parameters = (method->has_static) ? 1 : 2; | 3770 expected_num_parameters = (method->has_static) ? 1 : 2; |
3922 method->dict_name = &String::ZoneHandle(Z, | 3771 method->dict_name = &String::ZoneHandle( |
3923 Symbols::FromConcat(T, *method->name, Symbols::Equals())); | 3772 Z, Symbols::FromConcat(T, *method->name, Symbols::Equals())); |
3924 method->name = &String::ZoneHandle(Z, Field::SetterSymbol(*method->name)); | 3773 method->name = &String::ZoneHandle(Z, Field::SetterSymbol(*method->name)); |
3925 } | 3774 } |
3926 if ((method->params.num_fixed_parameters != expected_num_parameters) || | 3775 if ((method->params.num_fixed_parameters != expected_num_parameters) || |
3927 (method->params.num_optional_parameters != 0)) { | 3776 (method->params.num_optional_parameters != 0)) { |
3928 ReportError(method->name_pos, "illegal %s parameters", | 3777 ReportError(method->name_pos, "illegal %s parameters", |
3929 method->IsGetter() ? "getter" : "setter"); | 3778 method->IsGetter() ? "getter" : "setter"); |
3930 } | 3779 } |
3931 } | 3780 } |
3932 | 3781 |
3933 // Parse redirecting factory constructor. | 3782 // Parse redirecting factory constructor. |
3934 Type& redirection_type = Type::Handle(Z); | 3783 Type& redirection_type = Type::Handle(Z); |
3935 String& redirection_identifier = String::Handle(Z); | 3784 String& redirection_identifier = String::Handle(Z); |
3936 bool is_redirecting = false; | 3785 bool is_redirecting = false; |
3937 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { | 3786 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
3938 // Default parameter values are disallowed in redirecting factories. | 3787 // Default parameter values are disallowed in redirecting factories. |
3939 if (method->params.has_explicit_default_values) { | 3788 if (method->params.has_explicit_default_values) { |
3940 ReportError("redirecting factory '%s' may not specify default values " | 3789 ReportError( |
3941 "for optional parameters", | 3790 "redirecting factory '%s' may not specify default values " |
3942 method->name->ToCString()); | 3791 "for optional parameters", |
| 3792 method->name->ToCString()); |
3943 } | 3793 } |
3944 if (method->has_external) { | 3794 if (method->has_external) { |
3945 ReportError(TokenPos(), | 3795 ReportError(TokenPos(), |
3946 "external factory constructor '%s' may not have redirection", | 3796 "external factory constructor '%s' may not have redirection", |
3947 method->name->ToCString()); | 3797 method->name->ToCString()); |
3948 } | 3798 } |
3949 ConsumeToken(); | 3799 ConsumeToken(); |
3950 const TokenPosition type_pos = TokenPos(); | 3800 const TokenPosition type_pos = TokenPos(); |
3951 is_redirecting = true; | 3801 is_redirecting = true; |
3952 const bool consume_unresolved_prefix = | 3802 const bool consume_unresolved_prefix = |
3953 (LookaheadToken(3) == Token::kLT) || | 3803 (LookaheadToken(3) == Token::kLT) || |
3954 (LookaheadToken(3) == Token::kPERIOD); | 3804 (LookaheadToken(3) == Token::kPERIOD); |
3955 const AbstractType& type = AbstractType::Handle(Z, | 3805 const AbstractType& type = AbstractType::Handle( |
3956 ParseType(ClassFinalizer::kResolveTypeParameters, | 3806 Z, ParseType(ClassFinalizer::kResolveTypeParameters, true, |
3957 true, | 3807 consume_unresolved_prefix)); |
3958 consume_unresolved_prefix)); | |
3959 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3808 if (!type.IsMalformed() && type.IsTypeParameter()) { |
3960 // Replace the type with a malformed type and compile a throw when called. | 3809 // Replace the type with a malformed type and compile a throw when called. |
3961 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 3810 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
3962 Error::Handle(Z), // No previous error. | 3811 Error::Handle(Z), // No previous error. |
3963 script_, | 3812 script_, type_pos, |
3964 type_pos, | |
3965 "factory '%s' may not redirect to type parameter '%s'", | 3813 "factory '%s' may not redirect to type parameter '%s'", |
3966 method->name->ToCString(), | 3814 method->name->ToCString(), |
3967 String::Handle(Z, type.UserVisibleName()).ToCString()); | 3815 String::Handle(Z, type.UserVisibleName()).ToCString()); |
3968 } else { | 3816 } else { |
3969 // We handle malformed and malbounded redirection type at run time. | 3817 // We handle malformed and malbounded redirection type at run time. |
3970 redirection_type ^= type.raw(); | 3818 redirection_type ^= type.raw(); |
3971 } | 3819 } |
3972 if (CurrentToken() == Token::kPERIOD) { | 3820 if (CurrentToken() == Token::kPERIOD) { |
3973 // Named constructor or factory. | 3821 // Named constructor or factory. |
3974 ConsumeToken(); | 3822 ConsumeToken(); |
(...skipping 10 matching lines...) Expand all Loading... |
3985 method->name->ToCString()); | 3833 method->name->ToCString()); |
3986 } | 3834 } |
3987 if ((LookaheadToken(1) == Token::kTHIS) && | 3835 if ((LookaheadToken(1) == Token::kTHIS) && |
3988 ((LookaheadToken(2) == Token::kLPAREN) || | 3836 ((LookaheadToken(2) == Token::kLPAREN) || |
3989 LookaheadToken(4) == Token::kLPAREN)) { | 3837 LookaheadToken(4) == Token::kLPAREN)) { |
3990 // Redirected constructor: either this(...) or this.xxx(...). | 3838 // Redirected constructor: either this(...) or this.xxx(...). |
3991 is_redirecting = true; | 3839 is_redirecting = true; |
3992 if (method->params.has_field_initializer) { | 3840 if (method->params.has_field_initializer) { |
3993 // Constructors that redirect to another constructor must not | 3841 // Constructors that redirect to another constructor must not |
3994 // initialize any fields using field initializer parameters. | 3842 // initialize any fields using field initializer parameters. |
3995 ReportError(formal_param_pos, "Redirecting constructor " | 3843 ReportError(formal_param_pos, |
| 3844 "Redirecting constructor " |
3996 "may not use field initializer parameters"); | 3845 "may not use field initializer parameters"); |
3997 } | 3846 } |
3998 ConsumeToken(); // Colon. | 3847 ConsumeToken(); // Colon. |
3999 ExpectToken(Token::kTHIS); | 3848 ExpectToken(Token::kTHIS); |
4000 GrowableHandlePtrArray<const String> pieces(Z, 3); | 3849 GrowableHandlePtrArray<const String> pieces(Z, 3); |
4001 pieces.Add(members->class_name()); | 3850 pieces.Add(members->class_name()); |
4002 pieces.Add(Symbols::Dot()); | 3851 pieces.Add(Symbols::Dot()); |
4003 if (CurrentToken() == Token::kPERIOD) { | 3852 if (CurrentToken() == Token::kPERIOD) { |
4004 ConsumeToken(); | 3853 ConsumeToken(); |
4005 pieces.Add(*ExpectIdentifier("constructor name expected")); | 3854 pieces.Add(*ExpectIdentifier("constructor name expected")); |
4006 } | 3855 } |
4007 String& redir_name = | 3856 String& redir_name = |
4008 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); | 3857 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); |
4009 | 3858 |
4010 method->redirect_name = &redir_name; | 3859 method->redirect_name = &redir_name; |
4011 CheckToken(Token::kLPAREN); | 3860 CheckToken(Token::kLPAREN); |
4012 SkipToMatchingParenthesis(); | 3861 SkipToMatchingParenthesis(); |
4013 } else { | 3862 } else { |
4014 SkipInitializers(); | 3863 SkipInitializers(); |
4015 } | 3864 } |
4016 } | 3865 } |
4017 | 3866 |
4018 // Only constructors can redirect to another method. | 3867 // Only constructors can redirect to another method. |
4019 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3868 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
4020 | 3869 |
4021 if (method->IsConstructor() && | 3870 if (method->IsConstructor() && method->has_external && |
4022 method->has_external && | |
4023 method->params.has_field_initializer) { | 3871 method->params.has_field_initializer) { |
4024 ReportError(method->name_pos, | 3872 ReportError(method->name_pos, |
4025 "external constructor '%s' may not have field initializers", | 3873 "external constructor '%s' may not have field initializers", |
4026 method->name->ToCString()); | 3874 method->name->ToCString()); |
4027 } | 3875 } |
4028 | 3876 |
4029 const TokenPosition modifier_pos = TokenPos(); | 3877 const TokenPosition modifier_pos = TokenPos(); |
4030 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | 3878 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
4031 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && | 3879 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && |
4032 (async_modifier != RawFunction::kNoModifier)) { | 3880 (async_modifier != RawFunction::kNoModifier)) { |
4033 ReportError(modifier_pos, | 3881 ReportError(modifier_pos, "%s '%s' may not be async, async* or sync*", |
4034 "%s '%s' may not be async, async* or sync*", | |
4035 (method->IsSetter()) ? "setter" : "constructor", | 3882 (method->IsSetter()) ? "setter" : "constructor", |
4036 method->name->ToCString()); | 3883 method->name->ToCString()); |
4037 } | 3884 } |
4038 | 3885 |
4039 TokenPosition method_end_pos = TokenPos(); | 3886 TokenPosition method_end_pos = TokenPos(); |
4040 String* native_name = NULL; | 3887 String* native_name = NULL; |
4041 if ((CurrentToken() == Token::kLBRACE) || | 3888 if ((CurrentToken() == Token::kLBRACE) || (CurrentToken() == Token::kARROW)) { |
4042 (CurrentToken() == Token::kARROW)) { | |
4043 if (method->has_abstract) { | 3889 if (method->has_abstract) { |
4044 ReportError(TokenPos(), | 3890 ReportError(TokenPos(), |
4045 "abstract method '%s' may not have a function body", | 3891 "abstract method '%s' may not have a function body", |
4046 method->name->ToCString()); | 3892 method->name->ToCString()); |
4047 } else if (method->has_external) { | 3893 } else if (method->has_external) { |
4048 ReportError(TokenPos(), | 3894 ReportError(TokenPos(), "external %s '%s' may not have a function body", |
4049 "external %s '%s' may not have a function body", | |
4050 method->IsFactoryOrConstructor() ? "constructor" : "method", | 3895 method->IsFactoryOrConstructor() ? "constructor" : "method", |
4051 method->name->ToCString()); | 3896 method->name->ToCString()); |
4052 } else if (method->IsConstructor() && method->has_const) { | 3897 } else if (method->IsConstructor() && method->has_const) { |
4053 ReportError(TokenPos(), | 3898 ReportError(TokenPos(), |
4054 "const constructor '%s' may not have a function body", | 3899 "const constructor '%s' may not have a function body", |
4055 method->name->ToCString()); | 3900 method->name->ToCString()); |
4056 } else if (method->IsFactory() && method->has_const) { | 3901 } else if (method->IsFactory() && method->has_const) { |
4057 ReportError(TokenPos(), | 3902 ReportError(TokenPos(), "const factory '%s' may not have a function body", |
4058 "const factory '%s' may not have a function body", | |
4059 method->name->ToCString()); | 3903 method->name->ToCString()); |
4060 } | 3904 } |
4061 if (method->redirect_name != NULL) { | 3905 if (method->redirect_name != NULL) { |
4062 ReportError(method->name_pos, | 3906 ReportError(method->name_pos, |
4063 "Constructor with redirection may not have a function body"); | 3907 "Constructor with redirection may not have a function body"); |
4064 } | 3908 } |
4065 if (CurrentToken() == Token::kLBRACE) { | 3909 if (CurrentToken() == Token::kLBRACE) { |
4066 SkipBlock(); | 3910 SkipBlock(); |
4067 method_end_pos = TokenPos(); | 3911 method_end_pos = TokenPos(); |
4068 ExpectToken(Token::kRBRACE); | 3912 ExpectToken(Token::kRBRACE); |
4069 } else { | 3913 } else { |
4070 if ((async_modifier & RawFunction::kGeneratorBit) != 0) { | 3914 if ((async_modifier & RawFunction::kGeneratorBit) != 0) { |
4071 ReportError(modifier_pos, | 3915 ReportError(modifier_pos, |
4072 "=> style function may not be sync* or async* generator"); | 3916 "=> style function may not be sync* or async* generator"); |
4073 } | 3917 } |
4074 | 3918 |
4075 ConsumeToken(); | 3919 ConsumeToken(); |
4076 BoolScope allow_await(&this->await_is_keyword_, | 3920 BoolScope allow_await(&this->await_is_keyword_, |
4077 async_modifier != RawFunction::kNoModifier); | 3921 async_modifier != RawFunction::kNoModifier); |
4078 SkipExpr(); | 3922 SkipExpr(); |
4079 method_end_pos = TokenPos(); | 3923 method_end_pos = TokenPos(); |
4080 ExpectSemicolon(); | 3924 ExpectSemicolon(); |
4081 } | 3925 } |
4082 } else if (IsSymbol(Symbols::Native())) { | 3926 } else if (IsSymbol(Symbols::Native())) { |
4083 if (method->has_abstract) { | 3927 if (method->has_abstract) { |
4084 ReportError(method->name_pos, | 3928 ReportError(method->name_pos, |
4085 "abstract method '%s' may not have a function body", | 3929 "abstract method '%s' may not have a function body", |
4086 method->name->ToCString()); | 3930 method->name->ToCString()); |
4087 } else if (method->IsConstructor() && method->has_const) { | 3931 } else if (method->IsConstructor() && method->has_const) { |
4088 ReportError(method->name_pos, | 3932 ReportError(method->name_pos, "const constructor '%s' may not be native", |
4089 "const constructor '%s' may not be native", | |
4090 method->name->ToCString()); | 3933 method->name->ToCString()); |
4091 } | 3934 } |
4092 if (method->redirect_name != NULL) { | 3935 if (method->redirect_name != NULL) { |
4093 ReportError(method->name_pos, | 3936 ReportError(method->name_pos, |
4094 "Constructor with redirection may not have a function body"); | 3937 "Constructor with redirection may not have a function body"); |
4095 } | 3938 } |
4096 native_name = &ParseNativeDeclaration(); | 3939 native_name = &ParseNativeDeclaration(); |
4097 method_end_pos = TokenPos(); | 3940 method_end_pos = TokenPos(); |
4098 ExpectSemicolon(); | 3941 ExpectSemicolon(); |
4099 method->has_native = true; | 3942 method->has_native = true; |
4100 } else { | 3943 } else { |
4101 // We haven't found a method body. Issue error if one is required. | 3944 // We haven't found a method body. Issue error if one is required. |
4102 const bool must_have_body = | 3945 const bool must_have_body = method->has_static && !method->has_external && |
4103 method->has_static && | 3946 redirection_type.IsNull(); |
4104 !method->has_external && | |
4105 redirection_type.IsNull(); | |
4106 if (must_have_body) { | 3947 if (must_have_body) { |
4107 ReportError(method->name_pos, | 3948 ReportError(method->name_pos, "function body expected for method '%s'", |
4108 "function body expected for method '%s'", | |
4109 method->name->ToCString()); | 3949 method->name->ToCString()); |
4110 } | 3950 } |
4111 | 3951 |
4112 if (CurrentToken() == Token::kSEMICOLON) { | 3952 if (CurrentToken() == Token::kSEMICOLON) { |
4113 ConsumeToken(); | 3953 ConsumeToken(); |
4114 if (!method->has_static && | 3954 if (!method->has_static && !method->has_external && |
4115 !method->has_external && | |
4116 !method->IsConstructor()) { | 3955 !method->IsConstructor()) { |
4117 // Methods, getters and setters without a body are | 3956 // Methods, getters and setters without a body are |
4118 // implicitly abstract. | 3957 // implicitly abstract. |
4119 method->has_abstract = true; | 3958 method->has_abstract = true; |
4120 } | 3959 } |
4121 } else { | 3960 } else { |
4122 // Signature is not followed by semicolon or body. Issue an | 3961 // Signature is not followed by semicolon or body. Issue an |
4123 // appropriate error. | 3962 // appropriate error. |
4124 const bool must_have_semicolon = | 3963 const bool must_have_semicolon = |
4125 (method->redirect_name != NULL) || | 3964 (method->redirect_name != NULL) || |
4126 (method->IsConstructor() && method->has_const) || | 3965 (method->IsConstructor() && method->has_const) || |
4127 method->has_external; | 3966 method->has_external; |
4128 if (must_have_semicolon) { | 3967 if (must_have_semicolon) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4181 innermost_function_ = Function::null(); | 4020 innermost_function_ = Function::null(); |
4182 members->AddFunction(func); | 4021 members->AddFunction(func); |
4183 } | 4022 } |
4184 | 4023 |
4185 | 4024 |
4186 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 4025 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
4187 TRACE_PARSER("ParseFieldDefinition"); | 4026 TRACE_PARSER("ParseFieldDefinition"); |
4188 // The parser has read the first field name and is now at the token | 4027 // The parser has read the first field name and is now at the token |
4189 // after the field name. | 4028 // after the field name. |
4190 ASSERT(CurrentToken() == Token::kSEMICOLON || | 4029 ASSERT(CurrentToken() == Token::kSEMICOLON || |
4191 CurrentToken() == Token::kCOMMA || | 4030 CurrentToken() == Token::kCOMMA || CurrentToken() == Token::kASSIGN); |
4192 CurrentToken() == Token::kASSIGN); | |
4193 ASSERT(field->type != NULL); | 4031 ASSERT(field->type != NULL); |
4194 ASSERT(field->name_pos.IsReal()); | 4032 ASSERT(field->name_pos.IsReal()); |
4195 ASSERT(current_member_ == field); | 4033 ASSERT(current_member_ == field); |
4196 // All const fields are also final. | 4034 // All const fields are also final. |
4197 ASSERT(!field->has_const || field->has_final); | 4035 ASSERT(!field->has_const || field->has_final); |
4198 | 4036 |
4199 if (field->has_abstract) { | 4037 if (field->has_abstract) { |
4200 ReportError("keyword 'abstract' not allowed in field declaration"); | 4038 ReportError("keyword 'abstract' not allowed in field declaration"); |
4201 } | 4039 } |
4202 if (field->has_external) { | 4040 if (field->has_external) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4242 ReportError(field->name_pos, | 4080 ReportError(field->name_pos, |
4243 "static %s field '%s' must have an initializer expression", | 4081 "static %s field '%s' must have an initializer expression", |
4244 field->has_const ? "const" : "final", | 4082 field->has_const ? "const" : "final", |
4245 field->name->ToCString()); | 4083 field->name->ToCString()); |
4246 } | 4084 } |
4247 } | 4085 } |
4248 | 4086 |
4249 // Create the field object. | 4087 // Create the field object. |
4250 const bool is_reflectable = | 4088 const bool is_reflectable = |
4251 !(library_.is_dart_scheme() && library_.IsPrivate(*field->name)); | 4089 !(library_.is_dart_scheme() && library_.IsPrivate(*field->name)); |
4252 class_field = Field::New(*field->name, | 4090 class_field = Field::New(*field->name, field->has_static, field->has_final, |
4253 field->has_static, | 4091 field->has_const, is_reflectable, current_class(), |
4254 field->has_final, | 4092 *field->type, field->name_pos); |
4255 field->has_const, | |
4256 is_reflectable, | |
4257 current_class(), | |
4258 *field->type, | |
4259 field->name_pos); | |
4260 class_field.set_has_initializer(has_initializer); | 4093 class_field.set_has_initializer(has_initializer); |
4261 members->AddField(class_field); | 4094 members->AddField(class_field); |
4262 field->field_ = &class_field; | 4095 field->field_ = &class_field; |
4263 if (is_patch_source() && IsPatchAnnotation(field->metadata_pos)) { | 4096 if (is_patch_source() && IsPatchAnnotation(field->metadata_pos)) { |
4264 // Currently, we just ignore the patch annotation on fields. | 4097 // Currently, we just ignore the patch annotation on fields. |
4265 // All fields in the patch class are added to the patched class. | 4098 // All fields in the patch class are added to the patched class. |
4266 field->metadata_pos = TokenPosition::kNoSource; | 4099 field->metadata_pos = TokenPosition::kNoSource; |
4267 } | 4100 } |
4268 if (FLAG_enable_mirrors && (field->metadata_pos.IsReal())) { | 4101 if (FLAG_enable_mirrors && (field->metadata_pos.IsReal())) { |
4269 library_.AddFieldMetadata(class_field, field->metadata_pos); | 4102 library_.AddFieldMetadata(class_field, field->metadata_pos); |
4270 } | 4103 } |
4271 | 4104 |
4272 // Start tracking types for fields with simple initializers in their | 4105 // Start tracking types for fields with simple initializers in their |
4273 // definition. This avoids some of the overhead to track this at runtime | 4106 // definition. This avoids some of the overhead to track this at runtime |
4274 // and rules out many fields from being unnecessary unboxing candidates. | 4107 // and rules out many fields from being unnecessary unboxing candidates. |
4275 if (!field->has_static && has_initializer && has_simple_literal) { | 4108 if (!field->has_static && has_initializer && has_simple_literal) { |
4276 class_field.RecordStore(init_value); | 4109 class_field.RecordStore(init_value); |
4277 if (!init_value.IsNull() && init_value.IsDouble()) { | 4110 if (!init_value.IsNull() && init_value.IsDouble()) { |
4278 class_field.set_is_double_initialized(true); | 4111 class_field.set_is_double_initialized(true); |
4279 } | 4112 } |
4280 } | 4113 } |
4281 | 4114 |
4282 // For static final fields (this includes static const fields), set value to | 4115 // For static final fields (this includes static const fields), set value to |
4283 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. | 4116 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. |
4284 if (field->has_static && has_initializer) { | 4117 if (field->has_static && has_initializer) { |
4285 class_field.SetStaticValue(init_value, true); | 4118 class_field.SetStaticValue(init_value, true); |
4286 if (!has_simple_literal) { | 4119 if (!has_simple_literal) { |
4287 String& getter_name = | 4120 String& getter_name = |
4288 String::Handle(Z, Field::GetterSymbol(*field->name)); | 4121 String::Handle(Z, Field::GetterSymbol(*field->name)); |
4289 getter = Function::New(getter_name, | 4122 getter = Function::New( |
4290 RawFunction::kImplicitStaticFinalGetter, | 4123 getter_name, RawFunction::kImplicitStaticFinalGetter, |
4291 field->has_static, | 4124 field->has_static, field->has_const, |
4292 field->has_const, | 4125 /* is_abstract = */ false, |
4293 /* is_abstract = */ false, | 4126 /* is_external = */ false, |
4294 /* is_external = */ false, | 4127 /* is_native = */ false, current_class(), field->name_pos); |
4295 /* is_native = */ false, | |
4296 current_class(), | |
4297 field->name_pos); | |
4298 getter.set_result_type(*field->type); | 4128 getter.set_result_type(*field->type); |
4299 getter.set_is_debuggable(false); | 4129 getter.set_is_debuggable(false); |
4300 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { | 4130 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { |
4301 getter.set_is_reflectable(false); | 4131 getter.set_is_reflectable(false); |
4302 } | 4132 } |
4303 members->AddFunction(getter); | 4133 members->AddFunction(getter); |
4304 } | 4134 } |
4305 } | 4135 } |
4306 | 4136 |
4307 // For instance fields, we create implicit getter and setter methods. | 4137 // For instance fields, we create implicit getter and setter methods. |
4308 if (!field->has_static) { | 4138 if (!field->has_static) { |
4309 String& getter_name = | 4139 String& getter_name = |
4310 String::Handle(Z, Field::GetterSymbol(*field->name)); | 4140 String::Handle(Z, Field::GetterSymbol(*field->name)); |
4311 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 4141 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
4312 field->has_static, | 4142 field->has_static, field->has_final, |
4313 field->has_final, | |
4314 /* is_abstract = */ false, | 4143 /* is_abstract = */ false, |
4315 /* is_external = */ false, | 4144 /* is_external = */ false, |
4316 /* is_native = */ false, | 4145 /* is_native = */ false, current_class(), |
4317 current_class(), | |
4318 field->name_pos); | 4146 field->name_pos); |
4319 ParamList params; | 4147 ParamList params; |
4320 ASSERT(current_class().raw() == getter.Owner()); | 4148 ASSERT(current_class().raw() == getter.Owner()); |
4321 params.AddReceiver(ReceiverType(current_class()), field->name_pos); | 4149 params.AddReceiver(ReceiverType(current_class()), field->name_pos); |
4322 getter.set_result_type(*field->type); | 4150 getter.set_result_type(*field->type); |
4323 getter.set_is_debuggable(false); | 4151 getter.set_is_debuggable(false); |
4324 AddFormalParamsToFunction(¶ms, getter); | 4152 AddFormalParamsToFunction(¶ms, getter); |
4325 members->AddFunction(getter); | 4153 members->AddFunction(getter); |
4326 if (!field->has_final) { | 4154 if (!field->has_final) { |
4327 // Build a setter accessor for non-const fields. | 4155 // Build a setter accessor for non-const fields. |
4328 String& setter_name = | 4156 String& setter_name = |
4329 String::Handle(Z, Field::SetterSymbol(*field->name)); | 4157 String::Handle(Z, Field::SetterSymbol(*field->name)); |
4330 setter = Function::New(setter_name, RawFunction::kImplicitSetter, | 4158 setter = Function::New(setter_name, RawFunction::kImplicitSetter, |
4331 field->has_static, | 4159 field->has_static, field->has_final, |
4332 field->has_final, | |
4333 /* is_abstract = */ false, | 4160 /* is_abstract = */ false, |
4334 /* is_external = */ false, | 4161 /* is_external = */ false, |
4335 /* is_native = */ false, | 4162 /* is_native = */ false, current_class(), |
4336 current_class(), | |
4337 field->name_pos); | 4163 field->name_pos); |
4338 ParamList params; | 4164 ParamList params; |
4339 ASSERT(current_class().raw() == setter.Owner()); | 4165 ASSERT(current_class().raw() == setter.Owner()); |
4340 params.AddReceiver(ReceiverType(current_class()), field->name_pos); | 4166 params.AddReceiver(ReceiverType(current_class()), field->name_pos); |
4341 params.AddFinalParameter(TokenPos(), | 4167 params.AddFinalParameter(TokenPos(), &Symbols::Value(), field->type); |
4342 &Symbols::Value(), | |
4343 field->type); | |
4344 setter.set_result_type(Object::void_type()); | 4168 setter.set_result_type(Object::void_type()); |
4345 setter.set_is_debuggable(false); | 4169 setter.set_is_debuggable(false); |
4346 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { | 4170 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { |
4347 setter.set_is_reflectable(false); | 4171 setter.set_is_reflectable(false); |
4348 } | 4172 } |
4349 AddFormalParamsToFunction(¶ms, setter); | 4173 AddFormalParamsToFunction(¶ms, setter); |
4350 members->AddFunction(setter); | 4174 members->AddFunction(setter); |
4351 } | 4175 } |
4352 } | 4176 } |
4353 | 4177 |
(...skipping 22 matching lines...) Expand all Loading... |
4376 member.params.has_optional_positional_parameters || | 4200 member.params.has_optional_positional_parameters || |
4377 member.params.has_optional_named_parameters || | 4201 member.params.has_optional_named_parameters || |
4378 (member.params.num_fixed_parameters != expected_num_parameters)) { | 4202 (member.params.num_fixed_parameters != expected_num_parameters)) { |
4379 // Subtract receiver when reporting number of expected arguments. | 4203 // Subtract receiver when reporting number of expected arguments. |
4380 ReportError(member.name_pos, "operator %s expects %" Pd " argument(s)", | 4204 ReportError(member.name_pos, "operator %s expects %" Pd " argument(s)", |
4381 member.name->ToCString(), (expected_num_parameters - 1)); | 4205 member.name->ToCString(), (expected_num_parameters - 1)); |
4382 } | 4206 } |
4383 } | 4207 } |
4384 | 4208 |
4385 | 4209 |
4386 void Parser::CheckMemberNameConflict(ClassDesc* members, | 4210 void Parser::CheckMemberNameConflict(ClassDesc* members, MemberDesc* member) { |
4387 MemberDesc* member) { | |
4388 const String& name = *member->DictName(); | 4211 const String& name = *member->DictName(); |
4389 if (name.Equals(members->class_name())) { | 4212 if (name.Equals(members->class_name())) { |
4390 ReportError(member->name_pos, | 4213 ReportError(member->name_pos, "%s '%s' conflicts with class name", |
4391 "%s '%s' conflicts with class name", | 4214 member->ToCString(), name.ToCString()); |
4392 member->ToCString(), | |
4393 name.ToCString()); | |
4394 } | 4215 } |
4395 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { | 4216 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { |
4396 ReportError(member->name_pos, | 4217 ReportError(member->name_pos, "%s '%s' conflicts with type parameter", |
4397 "%s '%s' conflicts with type parameter", | 4218 member->ToCString(), name.ToCString()); |
4398 member->ToCString(), | |
4399 name.ToCString()); | |
4400 } | 4219 } |
4401 for (int i = 0; i < members->members().length(); i++) { | 4220 for (int i = 0; i < members->members().length(); i++) { |
4402 MemberDesc* existing_member = &members->members()[i]; | 4221 MemberDesc* existing_member = &members->members()[i]; |
4403 if (name.Equals(*existing_member->DictName())) { | 4222 if (name.Equals(*existing_member->DictName())) { |
4404 ReportError(member->name_pos, | 4223 ReportError( |
4405 "%s '%s' conflicts with previously declared %s", | 4224 member->name_pos, "%s '%s' conflicts with previously declared %s", |
4406 member->ToCString(), | 4225 member->ToCString(), name.ToCString(), existing_member->ToCString()); |
4407 name.ToCString(), | |
4408 existing_member->ToCString()); | |
4409 } | 4226 } |
4410 } | 4227 } |
4411 } | 4228 } |
4412 | 4229 |
4413 | 4230 |
4414 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 4231 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
4415 TokenPosition metadata_pos) { | 4232 TokenPosition metadata_pos) { |
4416 TRACE_PARSER("ParseClassMemberDefinition"); | 4233 TRACE_PARSER("ParseClassMemberDefinition"); |
4417 MemberDesc member; | 4234 MemberDesc member; |
4418 current_member_ = &member; | 4235 current_member_ = &member; |
(...skipping 21 matching lines...) Expand all Loading... |
4440 ReportError("identifier expected after 'const'"); | 4257 ReportError("identifier expected after 'const'"); |
4441 } | 4258 } |
4442 if (member.has_final) { | 4259 if (member.has_final) { |
4443 ReportError("identifier expected after 'final'"); | 4260 ReportError("identifier expected after 'final'"); |
4444 } | 4261 } |
4445 ConsumeToken(); | 4262 ConsumeToken(); |
4446 member.has_var = true; | 4263 member.has_var = true; |
4447 // The member type is the 'dynamic' type. | 4264 // The member type is the 'dynamic' type. |
4448 member.type = &Object::dynamic_type(); | 4265 member.type = &Object::dynamic_type(); |
4449 } else if ((CurrentToken() == Token::kFACTORY) && | 4266 } else if ((CurrentToken() == Token::kFACTORY) && |
4450 (LookaheadToken(1) != Token::kLPAREN)) { | 4267 (LookaheadToken(1) != Token::kLPAREN)) { |
4451 ConsumeToken(); | 4268 ConsumeToken(); |
4452 if (member.has_static) { | 4269 if (member.has_static) { |
4453 ReportError("factory method cannot be explicitly marked static"); | 4270 ReportError("factory method cannot be explicitly marked static"); |
4454 } | 4271 } |
4455 member.has_factory = true; | 4272 member.has_factory = true; |
4456 member.has_static = true; | 4273 member.has_static = true; |
4457 // The result type depends on the name of the factory method. | 4274 // The result type depends on the name of the factory method. |
4458 } | 4275 } |
4459 | 4276 |
4460 // Optionally parse a type. | 4277 // Optionally parse a type. |
4461 if (CurrentToken() == Token::kVOID) { | 4278 if (CurrentToken() == Token::kVOID) { |
4462 if (member.has_var || member.has_factory) { | 4279 if (member.has_var || member.has_factory) { |
4463 ReportError("void not expected"); | 4280 ReportError("void not expected"); |
4464 } | 4281 } |
4465 ConsumeToken(); | 4282 ConsumeToken(); |
4466 ASSERT(member.type == NULL); | 4283 ASSERT(member.type == NULL); |
4467 member.type = &Object::void_type(); | 4284 member.type = &Object::void_type(); |
4468 } else { | 4285 } else { |
4469 bool found_type = false; | 4286 bool found_type = false; |
4470 { | 4287 { |
4471 // Lookahead to determine whether the next tokens are a return type. | 4288 // Lookahead to determine whether the next tokens are a return type. |
4472 TokenPosScope saved_pos(this); | 4289 TokenPosScope saved_pos(this); |
4473 if (TryParseReturnType()) { | 4290 if (TryParseReturnType()) { |
4474 if (IsIdentifier() || | 4291 if (IsIdentifier() || (CurrentToken() == Token::kGET) || |
4475 (CurrentToken() == Token::kGET) || | 4292 (CurrentToken() == Token::kSET) || |
4476 (CurrentToken() == Token::kSET) || | 4293 (CurrentToken() == Token::kOPERATOR)) { |
4477 (CurrentToken() == Token::kOPERATOR)) { | |
4478 found_type = true; | 4294 found_type = true; |
4479 } | 4295 } |
4480 } | 4296 } |
4481 } | 4297 } |
4482 if (found_type) { | 4298 if (found_type) { |
4483 // It is too early to resolve the type here, since it can be a result type | 4299 // It is too early to resolve the type here, since it can be a result type |
4484 // referring to a not yet declared function type parameter. | 4300 // referring to a not yet declared function type parameter. |
4485 member.type = &AbstractType::ZoneHandle(Z, | 4301 member.type = &AbstractType::ZoneHandle( |
4486 ParseType(ClassFinalizer::kDoNotResolve)); | 4302 Z, ParseType(ClassFinalizer::kDoNotResolve)); |
4487 } | 4303 } |
4488 } | 4304 } |
4489 | 4305 |
4490 // Optionally parse a (possibly named) constructor name or factory. | 4306 // Optionally parse a (possibly named) constructor name or factory. |
4491 if (IsIdentifier() && | 4307 if (IsIdentifier() && |
4492 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 4308 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
4493 member.name_pos = TokenPos(); | 4309 member.name_pos = TokenPos(); |
4494 member.name = CurrentLiteral(); // Unqualified identifier. | 4310 member.name = CurrentLiteral(); // Unqualified identifier. |
4495 ConsumeToken(); | 4311 ConsumeToken(); |
4496 if (member.has_factory) { | 4312 if (member.has_factory) { |
4497 // The factory name may be qualified, but the first identifier must match | 4313 // The factory name may be qualified, but the first identifier must match |
4498 // the name of the immediately enclosing class. | 4314 // the name of the immediately enclosing class. |
4499 if (!member.name->Equals(members->class_name())) { | 4315 if (!member.name->Equals(members->class_name())) { |
4500 ReportError(member.name_pos, "factory name must be '%s'", | 4316 ReportError(member.name_pos, "factory name must be '%s'", |
4501 members->class_name().ToCString()); | 4317 members->class_name().ToCString()); |
4502 } | 4318 } |
4503 } else if (member.has_static) { | 4319 } else if (member.has_static) { |
4504 ReportError(member.name_pos, "constructor cannot be static"); | 4320 ReportError(member.name_pos, "constructor cannot be static"); |
4505 } | 4321 } |
4506 if (member.type != NULL) { | 4322 if (member.type != NULL) { |
4507 ReportError(member.name_pos, "constructor must not specify return type"); | 4323 ReportError(member.name_pos, "constructor must not specify return type"); |
4508 } | 4324 } |
4509 // Do not bypass class resolution by using current_class() directly, since | 4325 // Do not bypass class resolution by using current_class() directly, since |
4510 // it may be a patch class. | 4326 // it may be a patch class. |
4511 const Object& result_type_class = Object::Handle(Z, | 4327 const Object& result_type_class = |
4512 UnresolvedClass::New(LibraryPrefix::Handle(Z), | 4328 Object::Handle(Z, UnresolvedClass::New(LibraryPrefix::Handle(Z), |
4513 *member.name, | 4329 *member.name, member.name_pos)); |
4514 member.name_pos)); | |
4515 // The type arguments of the result type are the type parameters of the | 4330 // The type arguments of the result type are the type parameters of the |
4516 // current class. Note that in the case of a patch class, they are copied | 4331 // current class. Note that in the case of a patch class, they are copied |
4517 // from the class being patched. | 4332 // from the class being patched. |
4518 member.type = &Type::ZoneHandle(Z, Type::New( | 4333 member.type = &Type::ZoneHandle( |
4519 result_type_class, | 4334 Z, |
4520 TypeArguments::Handle(Z, current_class().type_parameters()), | 4335 Type::New(result_type_class, |
4521 member.name_pos)); | 4336 TypeArguments::Handle(Z, current_class().type_parameters()), |
| 4337 member.name_pos)); |
4522 | 4338 |
4523 // We must be dealing with a constructor or named constructor. | 4339 // We must be dealing with a constructor or named constructor. |
4524 member.kind = RawFunction::kConstructor; | 4340 member.kind = RawFunction::kConstructor; |
4525 GrowableHandlePtrArray<const String> to_concat(Z, 3); | 4341 GrowableHandlePtrArray<const String> to_concat(Z, 3); |
4526 to_concat.Add(*member.name); | 4342 to_concat.Add(*member.name); |
4527 to_concat.Add(Symbols::Dot()); | 4343 to_concat.Add(Symbols::Dot()); |
4528 if (CurrentToken() == Token::kPERIOD) { | 4344 if (CurrentToken() == Token::kPERIOD) { |
4529 // Named constructor. | 4345 // Named constructor. |
4530 ConsumeToken(); | 4346 ConsumeToken(); |
4531 member.dict_name = ExpectIdentifier("identifier expected"); | 4347 member.dict_name = ExpectIdentifier("identifier expected"); |
4532 to_concat.Add(*member.dict_name); | 4348 to_concat.Add(*member.dict_name); |
4533 } | 4349 } |
4534 *member.name = Symbols::FromConcatAll(T, to_concat); | 4350 *member.name = Symbols::FromConcatAll(T, to_concat); |
4535 CheckToken(Token::kLPAREN); | 4351 CheckToken(Token::kLPAREN); |
4536 } else if ((CurrentToken() == Token::kGET) && !member.has_var && | 4352 } else if ((CurrentToken() == Token::kGET) && !member.has_var && |
4537 (LookaheadToken(1) != Token::kLPAREN) && | 4353 (LookaheadToken(1) != Token::kLPAREN) && |
4538 (LookaheadToken(1) != Token::kLT) && | 4354 (LookaheadToken(1) != Token::kLT) && |
4539 (LookaheadToken(1) != Token::kASSIGN) && | 4355 (LookaheadToken(1) != Token::kASSIGN) && |
4540 (LookaheadToken(1) != Token::kCOMMA) && | 4356 (LookaheadToken(1) != Token::kCOMMA) && |
4541 (LookaheadToken(1) != Token::kSEMICOLON)) { | 4357 (LookaheadToken(1) != Token::kSEMICOLON)) { |
4542 ConsumeToken(); | 4358 ConsumeToken(); |
4543 member.kind = RawFunction::kGetterFunction; | 4359 member.kind = RawFunction::kGetterFunction; |
4544 member.name_pos = this->TokenPos(); | 4360 member.name_pos = this->TokenPos(); |
4545 member.name = ExpectIdentifier("identifier expected"); | 4361 member.name = ExpectIdentifier("identifier expected"); |
4546 // If the result type was not specified, it will be set to DynamicType. | 4362 // If the result type was not specified, it will be set to DynamicType. |
4547 } else if ((CurrentToken() == Token::kSET) && !member.has_var && | 4363 } else if ((CurrentToken() == Token::kSET) && !member.has_var && |
4548 (LookaheadToken(1) != Token::kLPAREN) && | 4364 (LookaheadToken(1) != Token::kLPAREN) && |
4549 (LookaheadToken(1) != Token::kLT) && | 4365 (LookaheadToken(1) != Token::kLT) && |
4550 (LookaheadToken(1) != Token::kASSIGN) && | 4366 (LookaheadToken(1) != Token::kASSIGN) && |
4551 (LookaheadToken(1) != Token::kCOMMA) && | 4367 (LookaheadToken(1) != Token::kCOMMA) && |
4552 (LookaheadToken(1) != Token::kSEMICOLON)) { | 4368 (LookaheadToken(1) != Token::kSEMICOLON)) { |
4553 ConsumeToken(); | 4369 ConsumeToken(); |
4554 member.kind = RawFunction::kSetterFunction; | 4370 member.kind = RawFunction::kSetterFunction; |
4555 member.name_pos = this->TokenPos(); | 4371 member.name_pos = this->TokenPos(); |
4556 member.name = ExpectIdentifier("identifier expected"); | 4372 member.name = ExpectIdentifier("identifier expected"); |
4557 CheckToken(Token::kLPAREN); | 4373 CheckToken(Token::kLPAREN); |
4558 // The grammar allows a return type, so member.type is not always NULL here. | 4374 // The grammar allows a return type, so member.type is not always NULL here. |
4559 // If no return type is specified, the return type of the setter is dynamic. | 4375 // If no return type is specified, the return type of the setter is dynamic. |
4560 if (member.type == NULL) { | 4376 if (member.type == NULL) { |
4561 member.type = &Object::dynamic_type(); | 4377 member.type = &Object::dynamic_type(); |
4562 } | 4378 } |
4563 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && | 4379 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && |
4564 (LookaheadToken(1) != Token::kLPAREN) && | 4380 (LookaheadToken(1) != Token::kLPAREN) && |
4565 (LookaheadToken(1) != Token::kASSIGN) && | 4381 (LookaheadToken(1) != Token::kASSIGN) && |
4566 (LookaheadToken(1) != Token::kCOMMA) && | 4382 (LookaheadToken(1) != Token::kCOMMA) && |
4567 (LookaheadToken(1) != Token::kSEMICOLON)) { | 4383 (LookaheadToken(1) != Token::kSEMICOLON)) { |
4568 // TODO(hausner): handle the case of a generic function named 'operator': | 4384 // TODO(hausner): handle the case of a generic function named 'operator': |
4569 // eg: T operator<T>(a, b) => ... | 4385 // eg: T operator<T>(a, b) => ... |
4570 ConsumeToken(); | 4386 ConsumeToken(); |
4571 if (!Token::CanBeOverloaded(CurrentToken())) { | 4387 if (!Token::CanBeOverloaded(CurrentToken())) { |
4572 ReportError("invalid operator overloading"); | 4388 ReportError("invalid operator overloading"); |
4573 } | 4389 } |
4574 if (member.has_static) { | 4390 if (member.has_static) { |
4575 ReportError("operator overloading functions cannot be static"); | 4391 ReportError("operator overloading functions cannot be static"); |
4576 } | 4392 } |
4577 member.operator_token = CurrentToken(); | 4393 member.operator_token = CurrentToken(); |
4578 member.has_operator = true; | 4394 member.has_operator = true; |
4579 member.kind = RawFunction::kRegularFunction; | 4395 member.kind = RawFunction::kRegularFunction; |
4580 member.name_pos = this->TokenPos(); | 4396 member.name_pos = this->TokenPos(); |
4581 member.name = &String::ZoneHandle(Z, | 4397 member.name = |
4582 Symbols::Token(member.operator_token).raw()); | 4398 &String::ZoneHandle(Z, Symbols::Token(member.operator_token).raw()); |
4583 ConsumeToken(); | 4399 ConsumeToken(); |
4584 } else if (IsIdentifier()) { | 4400 } else if (IsIdentifier()) { |
4585 member.name = CurrentLiteral(); | 4401 member.name = CurrentLiteral(); |
4586 member.name_pos = TokenPos(); | 4402 member.name_pos = TokenPos(); |
4587 ConsumeToken(); | 4403 ConsumeToken(); |
4588 } else { | 4404 } else { |
4589 ReportError("identifier expected"); | 4405 ReportError("identifier expected"); |
4590 } | 4406 } |
4591 | 4407 |
4592 ASSERT(member.name != NULL); | 4408 ASSERT(member.name != NULL); |
4593 if (IsParameterPart() || member.IsGetter()) { | 4409 if (IsParameterPart() || member.IsGetter()) { |
4594 // Constructor or method. | 4410 // Constructor or method. |
4595 if (member.type == NULL) { | 4411 if (member.type == NULL) { |
4596 member.type = &Object::dynamic_type(); | 4412 member.type = &Object::dynamic_type(); |
4597 } | 4413 } |
4598 ASSERT(member.IsFactory() == member.has_factory); | 4414 ASSERT(member.IsFactory() == member.has_factory); |
4599 // Note that member.type may still be unresolved. | 4415 // Note that member.type may still be unresolved. |
4600 ParseMethodOrConstructor(members, &member); | 4416 ParseMethodOrConstructor(members, &member); |
4601 } else if (CurrentToken() == Token::kSEMICOLON || | 4417 } else if (CurrentToken() == Token::kSEMICOLON || |
4602 CurrentToken() == Token::kCOMMA || | 4418 CurrentToken() == Token::kCOMMA || |
4603 CurrentToken() == Token::kASSIGN) { | 4419 CurrentToken() == Token::kASSIGN) { |
4604 // Field definition. | 4420 // Field definition. |
4605 if (member.has_const) { | 4421 if (member.has_const) { |
4606 // const fields are implicitly final. | 4422 // const fields are implicitly final. |
4607 member.has_final = true; | 4423 member.has_final = true; |
4608 } | 4424 } |
4609 if (member.type == NULL) { | 4425 if (member.type == NULL) { |
4610 if (member.has_final) { | 4426 if (member.has_final) { |
4611 member.type = &Object::dynamic_type(); | 4427 member.type = &Object::dynamic_type(); |
4612 } else { | 4428 } else { |
4613 ReportError("missing 'var', 'final', 'const' or type" | 4429 ReportError( |
4614 " in field declaration"); | 4430 "missing 'var', 'final', 'const' or type" |
| 4431 " in field declaration"); |
4615 } | 4432 } |
4616 } else if (member.type->IsVoidType()) { | 4433 } else if (member.type->IsVoidType()) { |
4617 ReportError(member.name_pos, "field may not be 'void'"); | 4434 ReportError(member.name_pos, "field may not be 'void'"); |
4618 } | 4435 } |
4619 if (!member.type->IsResolved()) { | 4436 if (!member.type->IsResolved()) { |
4620 AbstractType& type = AbstractType::ZoneHandle(Z, member.type->raw()); | 4437 AbstractType& type = AbstractType::ZoneHandle(Z, member.type->raw()); |
4621 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); | 4438 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); |
4622 member.type = &type; | 4439 member.type = &type; |
4623 } | 4440 } |
4624 ParseFieldDefinition(members, &member); | 4441 ParseFieldDefinition(members, &member); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4680 } | 4497 } |
4681 | 4498 |
4682 | 4499 |
4683 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4500 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
4684 const Object& tl_owner, | 4501 const Object& tl_owner, |
4685 TokenPosition metadata_pos) { | 4502 TokenPosition metadata_pos) { |
4686 TRACE_PARSER("ParseClassDeclaration"); | 4503 TRACE_PARSER("ParseClassDeclaration"); |
4687 bool is_patch = false; | 4504 bool is_patch = false; |
4688 bool is_abstract = false; | 4505 bool is_abstract = false; |
4689 TokenPosition declaration_pos = | 4506 TokenPosition declaration_pos = |
4690 metadata_pos.IsReal() ? metadata_pos : TokenPos(); | 4507 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
4691 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 4508 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
4692 is_patch = true; | 4509 is_patch = true; |
4693 metadata_pos = TokenPosition::kNoSource; | 4510 metadata_pos = TokenPosition::kNoSource; |
4694 declaration_pos = TokenPos(); | 4511 declaration_pos = TokenPos(); |
4695 } else if (CurrentToken() == Token::kABSTRACT) { | 4512 } else if (CurrentToken() == Token::kABSTRACT) { |
4696 is_abstract = true; | 4513 is_abstract = true; |
4697 ConsumeToken(); | 4514 ConsumeToken(); |
4698 } | 4515 } |
4699 ExpectToken(Token::kCLASS); | 4516 ExpectToken(Token::kCLASS); |
4700 const TokenPosition classname_pos = TokenPos(); | 4517 const TokenPosition classname_pos = TokenPos(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4762 AbstractType& orig_bound = AbstractType::Handle(Z); | 4579 AbstractType& orig_bound = AbstractType::Handle(Z); |
4763 for (int i = 0; i < new_type_params_count; i++) { | 4580 for (int i = 0; i < new_type_params_count; i++) { |
4764 new_type_param ^= new_type_parameters.TypeAt(i); | 4581 new_type_param ^= new_type_parameters.TypeAt(i); |
4765 orig_type_param ^= orig_type_parameters.TypeAt(i); | 4582 orig_type_param ^= orig_type_parameters.TypeAt(i); |
4766 new_name = new_type_param.name(); | 4583 new_name = new_type_param.name(); |
4767 orig_name = orig_type_param.name(); | 4584 orig_name = orig_type_param.name(); |
4768 if (!new_name.Equals(orig_name)) { | 4585 if (!new_name.Equals(orig_name)) { |
4769 ReportError(new_type_param.token_pos(), | 4586 ReportError(new_type_param.token_pos(), |
4770 "type parameter '%s' of patch class '%s' does not match " | 4587 "type parameter '%s' of patch class '%s' does not match " |
4771 "original type parameter '%s'", | 4588 "original type parameter '%s'", |
4772 new_name.ToCString(), | 4589 new_name.ToCString(), class_name.ToCString(), |
4773 class_name.ToCString(), | |
4774 orig_name.ToCString()); | 4590 orig_name.ToCString()); |
4775 } | 4591 } |
4776 new_bound = new_type_param.bound(); | 4592 new_bound = new_type_param.bound(); |
4777 orig_bound = orig_type_param.bound(); | 4593 orig_bound = orig_type_param.bound(); |
4778 if (!new_bound.Equals(orig_bound)) { | 4594 if (!new_bound.Equals(orig_bound)) { |
4779 ReportError(new_type_param.token_pos(), | 4595 ReportError(new_type_param.token_pos(), |
4780 "bound '%s' of type parameter '%s' of patch class '%s' " | 4596 "bound '%s' of type parameter '%s' of patch class '%s' " |
4781 "does not match original type parameter bound '%s'", | 4597 "does not match original type parameter bound '%s'", |
4782 String::Handle(new_bound.UserVisibleName()).ToCString(), | 4598 String::Handle(new_bound.UserVisibleName()).ToCString(), |
4783 new_name.ToCString(), | 4599 new_name.ToCString(), class_name.ToCString(), |
4784 class_name.ToCString(), | |
4785 String::Handle(orig_bound.UserVisibleName()).ToCString()); | 4600 String::Handle(orig_bound.UserVisibleName()).ToCString()); |
4786 } | 4601 } |
4787 } | 4602 } |
4788 } | 4603 } |
4789 cls.set_type_parameters(orig_type_parameters); | 4604 cls.set_type_parameters(orig_type_parameters); |
4790 } | 4605 } |
4791 | 4606 |
4792 if (is_abstract) { | 4607 if (is_abstract) { |
4793 cls.set_is_abstract(); | 4608 cls.set_is_abstract(); |
4794 } | 4609 } |
(...skipping 11 matching lines...) Expand all Loading... |
4806 AbstractType& super_type = Type::Handle(Z); | 4621 AbstractType& super_type = Type::Handle(Z); |
4807 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 4622 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
4808 ConsumeToken(); // extends or = | 4623 ConsumeToken(); // extends or = |
4809 const TokenPosition type_pos = TokenPos(); | 4624 const TokenPosition type_pos = TokenPos(); |
4810 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4625 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
4811 if (super_type.IsMalformedOrMalbounded()) { | 4626 if (super_type.IsMalformedOrMalbounded()) { |
4812 ReportError(Error::Handle(Z, super_type.error())); | 4627 ReportError(Error::Handle(Z, super_type.error())); |
4813 } | 4628 } |
4814 if (super_type.IsDynamicType()) { | 4629 if (super_type.IsDynamicType()) { |
4815 // Unlikely here, since super type is not resolved yet. | 4630 // Unlikely here, since super type is not resolved yet. |
4816 ReportError(type_pos, | 4631 ReportError(type_pos, "class '%s' may not extend 'dynamic'", |
4817 "class '%s' may not extend 'dynamic'", | |
4818 class_name.ToCString()); | 4632 class_name.ToCString()); |
4819 } | 4633 } |
4820 if (super_type.IsTypeParameter()) { | 4634 if (super_type.IsTypeParameter()) { |
4821 ReportError(type_pos, | 4635 ReportError(type_pos, "class '%s' may not extend type parameter '%s'", |
4822 "class '%s' may not extend type parameter '%s'", | |
4823 class_name.ToCString(), | 4636 class_name.ToCString(), |
4824 String::Handle(Z, | 4637 String::Handle(Z, super_type.UserVisibleName()).ToCString()); |
4825 super_type.UserVisibleName()).ToCString()); | |
4826 } | 4638 } |
4827 // The class finalizer will check whether the super type is malbounded. | 4639 // The class finalizer will check whether the super type is malbounded. |
4828 if (is_mixin_declaration) { | 4640 if (is_mixin_declaration) { |
4829 if (CurrentToken() != Token::kWITH) { | 4641 if (CurrentToken() != Token::kWITH) { |
4830 ReportError("mixin application clause 'with type' expected"); | 4642 ReportError("mixin application clause 'with type' expected"); |
4831 } | 4643 } |
4832 cls.set_is_mixin_app_alias(); | 4644 cls.set_is_mixin_app_alias(); |
4833 cls.set_is_synthesized_class(); | 4645 cls.set_is_synthesized_class(); |
4834 } | 4646 } |
4835 if (CurrentToken() == Token::kWITH) { | 4647 if (CurrentToken() == Token::kWITH) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4888 ConsumeToken(); | 4700 ConsumeToken(); |
4889 } | 4701 } |
4890 ExpectToken(Token::kLBRACE); | 4702 ExpectToken(Token::kLBRACE); |
4891 while (CurrentToken() != Token::kRBRACE) { | 4703 while (CurrentToken() != Token::kRBRACE) { |
4892 TokenPosition metadata_pos = SkipMetadata(); | 4704 TokenPosition metadata_pos = SkipMetadata(); |
4893 ParseClassMemberDefinition(&members, metadata_pos); | 4705 ParseClassMemberDefinition(&members, metadata_pos); |
4894 } | 4706 } |
4895 ExpectToken(Token::kRBRACE); | 4707 ExpectToken(Token::kRBRACE); |
4896 | 4708 |
4897 if (cls.LookupTypeParameter(class_name) != TypeParameter::null()) { | 4709 if (cls.LookupTypeParameter(class_name) != TypeParameter::null()) { |
4898 ReportError(class_pos, | 4710 ReportError(class_pos, "class name conflicts with type parameter '%s'", |
4899 "class name conflicts with type parameter '%s'", | |
4900 class_name.ToCString()); | 4711 class_name.ToCString()); |
4901 } | 4712 } |
4902 CheckConstructors(&members); | 4713 CheckConstructors(&members); |
4903 | 4714 |
4904 // Need to compute this here since MakeArray() will clear the | 4715 // Need to compute this here since MakeArray() will clear the |
4905 // functions array in members. | 4716 // functions array in members. |
4906 const bool need_implicit_constructor = | 4717 const bool need_implicit_constructor = |
4907 !members.has_constructor() && !cls.is_patch(); | 4718 !members.has_constructor() && !cls.is_patch(); |
4908 | 4719 |
4909 cls.AddFields(members.fields()); | 4720 cls.AddFields(members.fields()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4955 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); | 4766 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); |
4956 | 4767 |
4957 // Add instance field 'final int index'. | 4768 // Add instance field 'final int index'. |
4958 Field& index_field = Field::ZoneHandle(Z); | 4769 Field& index_field = Field::ZoneHandle(Z); |
4959 const Type& int_type = Type::Handle(Z, Type::IntType()); | 4770 const Type& int_type = Type::Handle(Z, Type::IntType()); |
4960 index_field = Field::New(Symbols::Index(), | 4771 index_field = Field::New(Symbols::Index(), |
4961 false, // Not static. | 4772 false, // Not static. |
4962 true, // Field is final. | 4773 true, // Field is final. |
4963 false, // Not const. | 4774 false, // Not const. |
4964 true, // Is reflectable. | 4775 true, // Is reflectable. |
4965 cls, | 4776 cls, int_type, cls.token_pos()); |
4966 int_type, | |
4967 cls.token_pos()); | |
4968 enum_members.AddField(index_field); | 4777 enum_members.AddField(index_field); |
4969 | 4778 |
4970 // Add implicit getter for index field. | 4779 // Add implicit getter for index field. |
4971 const String& getter_name = | 4780 const String& getter_name = |
4972 String::Handle(Z, Field::GetterSymbol(Symbols::Index())); | 4781 String::Handle(Z, Field::GetterSymbol(Symbols::Index())); |
4973 Function& getter = Function::Handle(Z); | 4782 Function& getter = Function::Handle(Z); |
4974 getter = Function::New(getter_name, | 4783 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
4975 RawFunction::kImplicitGetter, | |
4976 /* is_static = */ false, | 4784 /* is_static = */ false, |
4977 /* is_const = */ true, | 4785 /* is_const = */ true, |
4978 /* is_abstract = */ false, | 4786 /* is_abstract = */ false, |
4979 /* is_external = */ false, | 4787 /* is_external = */ false, |
4980 /* is_native = */ false, | 4788 /* is_native = */ false, cls, cls.token_pos()); |
4981 cls, | |
4982 cls.token_pos()); | |
4983 getter.set_result_type(int_type); | 4789 getter.set_result_type(int_type); |
4984 getter.set_is_debuggable(false); | 4790 getter.set_is_debuggable(false); |
4985 ParamList params; | 4791 ParamList params; |
4986 params.AddReceiver(&Object::dynamic_type(), cls.token_pos()); | 4792 params.AddReceiver(&Object::dynamic_type(), cls.token_pos()); |
4987 AddFormalParamsToFunction(¶ms, getter); | 4793 AddFormalParamsToFunction(¶ms, getter); |
4988 enum_members.AddFunction(getter); | 4794 enum_members.AddFunction(getter); |
4989 | 4795 |
4990 ASSERT(IsIdentifier()); | 4796 ASSERT(IsIdentifier()); |
4991 ASSERT(CurrentLiteral()->raw() == cls.Name()); | 4797 ASSERT(CurrentLiteral()->raw() == cls.Name()); |
4992 | 4798 |
4993 ConsumeToken(); // Enum type name. | 4799 ConsumeToken(); // Enum type name. |
4994 ExpectToken(Token::kLBRACE); | 4800 ExpectToken(Token::kLBRACE); |
4995 Field& enum_value = Field::Handle(Z); | 4801 Field& enum_value = Field::Handle(Z); |
4996 intptr_t i = 0; | 4802 intptr_t i = 0; |
4997 GrowableArray<String*> declared_names(8); | 4803 GrowableArray<String*> declared_names(8); |
4998 | 4804 |
4999 while (IsIdentifier()) { | 4805 while (IsIdentifier()) { |
5000 String* enum_ident = CurrentLiteral(); | 4806 String* enum_ident = CurrentLiteral(); |
5001 | 4807 |
5002 // Check for name conflicts. | 4808 // Check for name conflicts. |
5003 if (enum_ident->raw() == cls.Name()) { | 4809 if (enum_ident->raw() == cls.Name()) { |
5004 ReportError("enum identifier '%s' cannot be equal to enum type name", | 4810 ReportError("enum identifier '%s' cannot be equal to enum type name", |
5005 CurrentLiteral()->ToCString()); | 4811 CurrentLiteral()->ToCString()); |
5006 } else if (enum_ident->raw() == Symbols::Index().raw()) { | 4812 } else if (enum_ident->raw() == Symbols::Index().raw()) { |
5007 ReportError("enum identifier conflicts with " | 4813 ReportError( |
5008 "implicit instance field 'index'"); | 4814 "enum identifier conflicts with " |
| 4815 "implicit instance field 'index'"); |
5009 } else if (enum_ident->raw() == Symbols::Values().raw()) { | 4816 } else if (enum_ident->raw() == Symbols::Values().raw()) { |
5010 ReportError("enum identifier conflicts with " | 4817 ReportError( |
5011 "implicit static field 'values'"); | 4818 "enum identifier conflicts with " |
| 4819 "implicit static field 'values'"); |
5012 } else if (enum_ident->raw() == Symbols::toString().raw()) { | 4820 } else if (enum_ident->raw() == Symbols::toString().raw()) { |
5013 ReportError("enum identifier conflicts with " | 4821 ReportError( |
5014 "implicit instance method 'toString()'"); | 4822 "enum identifier conflicts with " |
| 4823 "implicit instance method 'toString()'"); |
5015 } | 4824 } |
5016 for (intptr_t n = 0; n < declared_names.length(); n++) { | 4825 for (intptr_t n = 0; n < declared_names.length(); n++) { |
5017 if (enum_ident->Equals(*declared_names[n])) { | 4826 if (enum_ident->Equals(*declared_names[n])) { |
5018 ReportError("Duplicate name '%s' in enum definition '%s'", | 4827 ReportError("Duplicate name '%s' in enum definition '%s'", |
5019 enum_ident->ToCString(), | 4828 enum_ident->ToCString(), enum_name.ToCString()); |
5020 enum_name.ToCString()); | |
5021 } | 4829 } |
5022 } | 4830 } |
5023 declared_names.Add(enum_ident); | 4831 declared_names.Add(enum_ident); |
5024 | 4832 |
5025 // Create the static const field for the enumeration value. | 4833 // Create the static const field for the enumeration value. |
5026 enum_value = Field::New(*enum_ident, | 4834 enum_value = Field::New(*enum_ident, |
5027 /* is_static = */ true, | 4835 /* is_static = */ true, |
5028 /* is_final = */ true, | 4836 /* is_final = */ true, |
5029 /* is_const = */ true, | 4837 /* is_const = */ true, |
5030 /* is_reflectable = */ true, | 4838 /* is_reflectable = */ true, cls, |
5031 cls, | 4839 Object::dynamic_type(), cls.token_pos()); |
5032 Object::dynamic_type(), | |
5033 cls.token_pos()); | |
5034 enum_value.set_has_initializer(false); | 4840 enum_value.set_has_initializer(false); |
5035 enum_members.AddField(enum_value); | 4841 enum_members.AddField(enum_value); |
5036 // Initialize the field with the ordinal value. It will be patched | 4842 // Initialize the field with the ordinal value. It will be patched |
5037 // later with the enum constant instance. | 4843 // later with the enum constant instance. |
5038 const Smi& ordinal_value = Smi::Handle(Z, Smi::New(i)); | 4844 const Smi& ordinal_value = Smi::Handle(Z, Smi::New(i)); |
5039 enum_value.SetStaticValue(ordinal_value, true); | 4845 enum_value.SetStaticValue(ordinal_value, true); |
5040 enum_value.RecordStore(ordinal_value); | 4846 enum_value.RecordStore(ordinal_value); |
5041 i++; | 4847 i++; |
5042 | 4848 |
5043 ConsumeToken(); // Enum value name. | 4849 ConsumeToken(); // Enum value name. |
5044 if (CurrentToken() == Token::kCOMMA) { | 4850 if (CurrentToken() == Token::kCOMMA) { |
5045 ConsumeToken(); | 4851 ConsumeToken(); |
5046 } | 4852 } |
5047 } | 4853 } |
5048 ExpectToken(Token::kRBRACE); | 4854 ExpectToken(Token::kRBRACE); |
5049 | 4855 |
5050 // Add static field 'const List values'. | 4856 // Add static field 'const List values'. |
5051 Field& values_field = Field::ZoneHandle(Z); | 4857 Field& values_field = Field::ZoneHandle(Z); |
5052 values_field = Field::New(Symbols::Values(), | 4858 values_field = |
5053 /* is_static = */ true, | 4859 Field::New(Symbols::Values(), |
5054 /* is_final = */ true, | 4860 /* is_static = */ true, |
5055 /* is_const = */ true, | 4861 /* is_final = */ true, |
5056 /* is_reflectable = */ true, | 4862 /* is_const = */ true, |
5057 cls, | 4863 /* is_reflectable = */ true, cls, |
5058 Type::Handle(Z, Type::ArrayType()), | 4864 Type::Handle(Z, Type::ArrayType()), cls.token_pos()); |
5059 cls.token_pos()); | |
5060 enum_members.AddField(values_field); | 4865 enum_members.AddField(values_field); |
5061 | 4866 |
5062 // Allocate the immutable array containing the enumeration values. | 4867 // Allocate the immutable array containing the enumeration values. |
5063 // The actual enum instance values will be patched in later. | 4868 // The actual enum instance values will be patched in later. |
5064 const Array& values_array = Array::Handle(Z, Array::New(i, Heap::kOld)); | 4869 const Array& values_array = Array::Handle(Z, Array::New(i, Heap::kOld)); |
5065 values_field.SetStaticValue(values_array, true); | 4870 values_field.SetStaticValue(values_array, true); |
5066 values_field.RecordStore(values_array); | 4871 values_field.RecordStore(values_array); |
5067 | 4872 |
5068 // Clone the _name field from the helper class. | 4873 // Clone the _name field from the helper class. |
5069 Field& _name_field = Field::Handle(Z, | 4874 Field& _name_field = Field::Handle( |
5070 helper_class.LookupInstanceFieldAllowPrivate(Symbols::_name())); | 4875 Z, helper_class.LookupInstanceFieldAllowPrivate(Symbols::_name())); |
5071 ASSERT(!_name_field.IsNull()); | 4876 ASSERT(!_name_field.IsNull()); |
5072 _name_field = _name_field.Clone(cls); | 4877 _name_field = _name_field.Clone(cls); |
5073 enum_members.AddField(_name_field); | 4878 enum_members.AddField(_name_field); |
5074 | 4879 |
5075 // Add an implicit getter function for the _name field. We use the field's | 4880 // Add an implicit getter function for the _name field. We use the field's |
5076 // name directly here so that the private key matches those of the other | 4881 // name directly here so that the private key matches those of the other |
5077 // cloned helper functions and fields. | 4882 // cloned helper functions and fields. |
5078 const Type& string_type = Type::Handle(Z, Type::StringType()); | 4883 const Type& string_type = Type::Handle(Z, Type::StringType()); |
5079 const String& name_getter_name = String::Handle(Z, | 4884 const String& name_getter_name = String::Handle( |
5080 Field::GetterSymbol(String::Handle(_name_field.name()))); | 4885 Z, Field::GetterSymbol(String::Handle(_name_field.name()))); |
5081 Function& name_getter = Function::Handle(Z); | 4886 Function& name_getter = Function::Handle(Z); |
5082 name_getter = Function::New(name_getter_name, | 4887 name_getter = Function::New(name_getter_name, RawFunction::kImplicitGetter, |
5083 RawFunction::kImplicitGetter, | |
5084 /* is_static = */ false, | 4888 /* is_static = */ false, |
5085 /* is_const = */ true, | 4889 /* is_const = */ true, |
5086 /* is_abstract = */ false, | 4890 /* is_abstract = */ false, |
5087 /* is_external = */ false, | 4891 /* is_external = */ false, |
5088 /* is_native = */ false, | 4892 /* is_native = */ false, cls, cls.token_pos()); |
5089 cls, | |
5090 cls.token_pos()); | |
5091 name_getter.set_result_type(string_type); | 4893 name_getter.set_result_type(string_type); |
5092 name_getter.set_is_debuggable(false); | 4894 name_getter.set_is_debuggable(false); |
5093 ParamList name_params; | 4895 ParamList name_params; |
5094 name_params.AddReceiver(&Object::dynamic_type(), cls.token_pos()); | 4896 name_params.AddReceiver(&Object::dynamic_type(), cls.token_pos()); |
5095 AddFormalParamsToFunction(&name_params, name_getter); | 4897 AddFormalParamsToFunction(&name_params, name_getter); |
5096 enum_members.AddFunction(name_getter); | 4898 enum_members.AddFunction(name_getter); |
5097 | 4899 |
5098 // Clone the toString() function from the helper class. | 4900 // Clone the toString() function from the helper class. |
5099 Function& to_string_func = Function::Handle(Z, | 4901 Function& to_string_func = Function::Handle( |
5100 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); | 4902 Z, helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); |
5101 ASSERT(!to_string_func.IsNull()); | 4903 ASSERT(!to_string_func.IsNull()); |
5102 to_string_func = to_string_func.Clone(cls); | 4904 to_string_func = to_string_func.Clone(cls); |
5103 enum_members.AddFunction(to_string_func); | 4905 enum_members.AddFunction(to_string_func); |
5104 | 4906 |
5105 // Clone the hashCode getter function from the helper class. | 4907 // Clone the hashCode getter function from the helper class. |
5106 Function& hash_code_func = Function::Handle(Z, | 4908 Function& hash_code_func = Function::Handle( |
5107 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::hashCode())); | 4909 Z, helper_class.LookupDynamicFunctionAllowPrivate(Symbols::hashCode())); |
5108 ASSERT(!hash_code_func.IsNull()); | 4910 ASSERT(!hash_code_func.IsNull()); |
5109 hash_code_func = hash_code_func.Clone(cls); | 4911 hash_code_func = hash_code_func.Clone(cls); |
5110 enum_members.AddFunction(hash_code_func); | 4912 enum_members.AddFunction(hash_code_func); |
5111 | 4913 |
5112 cls.AddFields(enum_members.fields()); | 4914 cls.AddFields(enum_members.fields()); |
5113 const Array& functions = Array::Handle(Z, enum_members.MakeFunctionsArray()); | 4915 const Array& functions = Array::Handle(Z, enum_members.MakeFunctionsArray()); |
5114 cls.SetFunctions(functions); | 4916 cls.SetFunctions(functions); |
5115 } | 4917 } |
5116 | 4918 |
5117 | 4919 |
5118 // Add an implicit constructor to the given class. | 4920 // Add an implicit constructor to the given class. |
5119 void Parser::AddImplicitConstructor(const Class& cls) { | 4921 void Parser::AddImplicitConstructor(const Class& cls) { |
5120 // The implicit constructor is unnamed, has no explicit parameter. | 4922 // The implicit constructor is unnamed, has no explicit parameter. |
5121 String& ctor_name = String::ZoneHandle(Z, cls.Name()); | 4923 String& ctor_name = String::ZoneHandle(Z, cls.Name()); |
5122 ctor_name = Symbols::FromDot(T, ctor_name); | 4924 ctor_name = Symbols::FromDot(T, ctor_name); |
5123 // To indicate that this is an implicit constructor, we set the | 4925 // To indicate that this is an implicit constructor, we set the |
5124 // token position and end token position of the function | 4926 // token position and end token position of the function |
5125 // to the token position of the class. | 4927 // to the token position of the class. |
5126 Function& ctor = Function::Handle(Z, | 4928 Function& ctor = Function::Handle( |
5127 Function::New(ctor_name, | 4929 Z, Function::New(ctor_name, RawFunction::kConstructor, |
5128 RawFunction::kConstructor, | 4930 /* is_static = */ false, |
5129 /* is_static = */ false, | 4931 /* is_const = */ false, |
5130 /* is_const = */ false, | 4932 /* is_abstract = */ false, |
5131 /* is_abstract = */ false, | 4933 /* is_external = */ false, |
5132 /* is_external = */ false, | 4934 /* is_native = */ false, cls, cls.token_pos())); |
5133 /* is_native = */ false, | |
5134 cls, | |
5135 cls.token_pos())); | |
5136 ctor.set_end_token_pos(ctor.token_pos()); | 4935 ctor.set_end_token_pos(ctor.token_pos()); |
5137 ctor.set_is_debuggable(false); | 4936 ctor.set_is_debuggable(false); |
5138 if (library_.is_dart_scheme() && library_.IsPrivate(ctor_name)) { | 4937 if (library_.is_dart_scheme() && library_.IsPrivate(ctor_name)) { |
5139 ctor.set_is_reflectable(false); | 4938 ctor.set_is_reflectable(false); |
5140 } | 4939 } |
5141 | 4940 |
5142 ParamList params; | 4941 ParamList params; |
5143 // Add implicit 'this' parameter. | 4942 // Add implicit 'this' parameter. |
5144 const AbstractType* receiver_type = ReceiverType(cls); | 4943 const AbstractType* receiver_type = ReceiverType(cls); |
5145 params.AddReceiver(receiver_type, cls.token_pos()); | 4944 params.AddReceiver(receiver_type, cls.token_pos()); |
(...skipping 30 matching lines...) Expand all Loading... |
5176 // which the current one redirects, we ignore the unresolved | 4975 // which the current one redirects, we ignore the unresolved |
5177 // reference. We'll catch it later when the constructor gets | 4976 // reference. We'll catch it later when the constructor gets |
5178 // compiled. | 4977 // compiled. |
5179 ctors.Add(member); | 4978 ctors.Add(member); |
5180 member = class_desc->LookupMember(*member->redirect_name); | 4979 member = class_desc->LookupMember(*member->redirect_name); |
5181 } | 4980 } |
5182 } | 4981 } |
5183 } | 4982 } |
5184 | 4983 |
5185 | 4984 |
5186 void Parser::ParseMixinAppAlias( | 4985 void Parser::ParseMixinAppAlias(const GrowableObjectArray& pending_classes, |
5187 const GrowableObjectArray& pending_classes, | 4986 const Object& tl_owner, |
5188 const Object& tl_owner, | 4987 TokenPosition metadata_pos) { |
5189 TokenPosition metadata_pos) { | |
5190 TRACE_PARSER("ParseMixinAppAlias"); | 4988 TRACE_PARSER("ParseMixinAppAlias"); |
5191 const TokenPosition classname_pos = TokenPos(); | 4989 const TokenPosition classname_pos = TokenPos(); |
5192 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4990 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
5193 if (FLAG_trace_parser) { | 4991 if (FLAG_trace_parser) { |
5194 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4992 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
5195 class_name.ToCString()); | 4993 class_name.ToCString()); |
5196 } | 4994 } |
5197 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4995 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
5198 if (!obj.IsNull()) { | 4996 if (!obj.IsNull()) { |
5199 ReportError(classname_pos, "'%s' is already defined", | 4997 ReportError(classname_pos, "'%s' is already defined", |
5200 class_name.ToCString()); | 4998 class_name.ToCString()); |
5201 } | 4999 } |
5202 const Class& mixin_application = | 5000 const Class& mixin_application = Class::Handle( |
5203 Class::Handle(Z, Class::New(library_, class_name, | 5001 Z, Class::New(library_, class_name, script_, classname_pos)); |
5204 script_, classname_pos)); | |
5205 mixin_application.set_is_mixin_app_alias(); | 5002 mixin_application.set_is_mixin_app_alias(); |
5206 library_.AddClass(mixin_application); | 5003 library_.AddClass(mixin_application); |
5207 set_current_class(mixin_application); | 5004 set_current_class(mixin_application); |
5208 ParseTypeParameters(true); // Parameterizing current class. | 5005 ParseTypeParameters(true); // Parameterizing current class. |
5209 | 5006 |
5210 ExpectToken(Token::kASSIGN); | 5007 ExpectToken(Token::kASSIGN); |
5211 | 5008 |
5212 if (CurrentToken() == Token::kABSTRACT) { | 5009 if (CurrentToken() == Token::kABSTRACT) { |
5213 mixin_application.set_is_abstract(); | 5010 mixin_application.set_is_abstract(); |
5214 ConsumeToken(); | 5011 ConsumeToken(); |
5215 } | 5012 } |
5216 | 5013 |
5217 const TokenPosition type_pos = TokenPos(); | 5014 const TokenPosition type_pos = TokenPos(); |
5218 AbstractType& type = | 5015 AbstractType& type = AbstractType::Handle( |
5219 AbstractType::Handle(Z, | 5016 Z, ParseType(ClassFinalizer::kResolveTypeParameters)); |
5220 ParseType(ClassFinalizer::kResolveTypeParameters)); | |
5221 if (type.IsTypeParameter()) { | 5017 if (type.IsTypeParameter()) { |
5222 ReportError(type_pos, | 5018 ReportError(type_pos, "class '%s' may not extend type parameter '%s'", |
5223 "class '%s' may not extend type parameter '%s'", | |
5224 class_name.ToCString(), | 5019 class_name.ToCString(), |
5225 String::Handle(Z, type.UserVisibleName()).ToCString()); | 5020 String::Handle(Z, type.UserVisibleName()).ToCString()); |
5226 } | 5021 } |
5227 | 5022 |
5228 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 5023 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
5229 type = ParseMixins(type); | 5024 type = ParseMixins(type); |
5230 | 5025 |
5231 mixin_application.set_super_type(type); | 5026 mixin_application.set_super_type(type); |
5232 mixin_application.set_is_synthesized_class(); | 5027 mixin_application.set_is_synthesized_class(); |
5233 | 5028 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5310 | 5105 |
5311 const TokenPosition alias_name_pos = TokenPos(); | 5106 const TokenPosition alias_name_pos = TokenPos(); |
5312 const String* alias_name = | 5107 const String* alias_name = |
5313 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 5108 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
5314 | 5109 |
5315 // Lookup alias name and report an error if it is already defined in | 5110 // Lookup alias name and report an error if it is already defined in |
5316 // the library scope. | 5111 // the library scope. |
5317 const Object& obj = | 5112 const Object& obj = |
5318 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); | 5113 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); |
5319 if (!obj.IsNull()) { | 5114 if (!obj.IsNull()) { |
5320 ReportError(alias_name_pos, | 5115 ReportError(alias_name_pos, "'%s' is already defined", |
5321 "'%s' is already defined", alias_name->ToCString()); | 5116 alias_name->ToCString()); |
5322 } | 5117 } |
5323 | 5118 |
5324 // Create the function type alias scope class. It will be linked to its | 5119 // Create the function type alias scope class. It will be linked to its |
5325 // signature function after it has been parsed. The type parameters, in order | 5120 // signature function after it has been parsed. The type parameters, in order |
5326 // to be properly finalized, need to be associated to this scope class as | 5121 // to be properly finalized, need to be associated to this scope class as |
5327 // they are parsed. | 5122 // they are parsed. |
5328 const Class& function_type_alias = | 5123 const Class& function_type_alias = Class::Handle( |
5329 Class::Handle(Z, Class::New( | 5124 Z, Class::New(library_, *alias_name, script_, declaration_pos)); |
5330 library_, *alias_name, script_, declaration_pos)); | |
5331 function_type_alias.set_is_synthesized_class(); | 5125 function_type_alias.set_is_synthesized_class(); |
5332 function_type_alias.set_is_abstract(); | 5126 function_type_alias.set_is_abstract(); |
5333 function_type_alias.set_is_prefinalized(); | 5127 function_type_alias.set_is_prefinalized(); |
5334 library_.AddClass(function_type_alias); | 5128 library_.AddClass(function_type_alias); |
5335 set_current_class(function_type_alias); | 5129 set_current_class(function_type_alias); |
5336 // Parse the type parameters of the typedef class. | 5130 // Parse the type parameters of the typedef class. |
5337 ParseTypeParameters(true); // Parameterizing current class. | 5131 ParseTypeParameters(true); // Parameterizing current class. |
5338 // At this point, the type parameters have been parsed, so we can resolve the | 5132 // At this point, the type parameters have been parsed, so we can resolve the |
5339 // result type. | 5133 // result type. |
5340 if (!result_type.IsNull()) { | 5134 if (!result_type.IsNull()) { |
5341 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); | 5135 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); |
5342 } | 5136 } |
5343 // Parse the formal parameters of the function type. | 5137 // Parse the formal parameters of the function type. |
5344 CheckToken(Token::kLPAREN, "formal parameter list expected"); | 5138 CheckToken(Token::kLPAREN, "formal parameter list expected"); |
5345 ParamList func_params; | 5139 ParamList func_params; |
5346 | 5140 |
5347 // Add implicit closure object parameter. | 5141 // Add implicit closure object parameter. |
5348 func_params.AddFinalParameter( | 5142 func_params.AddFinalParameter(TokenPos(), &Symbols::ClosureParameter(), |
5349 TokenPos(), | 5143 &Object::dynamic_type()); |
5350 &Symbols::ClosureParameter(), | |
5351 &Object::dynamic_type()); | |
5352 | 5144 |
5353 // Mark the current class as a typedef class (by setting its signature | 5145 // Mark the current class as a typedef class (by setting its signature |
5354 // function field to a non-null function) before parsing its formal parameters | 5146 // function field to a non-null function) before parsing its formal parameters |
5355 // so that parsed function types are aware that their owner class is a | 5147 // so that parsed function types are aware that their owner class is a |
5356 // typedef class. | 5148 // typedef class. |
5357 Function& signature_function = | 5149 Function& signature_function = Function::Handle( |
5358 Function::Handle(Z, Function::NewSignatureFunction(function_type_alias, | 5150 Z, Function::NewSignatureFunction(function_type_alias, alias_name_pos)); |
5359 alias_name_pos)); | |
5360 ASSERT(innermost_function().IsNull()); | 5151 ASSERT(innermost_function().IsNull()); |
5361 innermost_function_ = signature_function.raw(); | 5152 innermost_function_ = signature_function.raw(); |
5362 // Set the signature function in the function type alias class. | 5153 // Set the signature function in the function type alias class. |
5363 function_type_alias.set_signature_function(signature_function); | 5154 function_type_alias.set_signature_function(signature_function); |
5364 | 5155 |
5365 const bool no_explicit_default_values = false; | 5156 const bool no_explicit_default_values = false; |
5366 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 5157 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
5367 ExpectSemicolon(); | 5158 ExpectSemicolon(); |
5368 signature_function.set_result_type(result_type); | 5159 signature_function.set_result_type(result_type); |
5369 AddFormalParamsToFunction(&func_params, signature_function); | 5160 AddFormalParamsToFunction(&func_params, signature_function); |
5370 | 5161 |
5371 ASSERT(innermost_function().raw() == signature_function.raw()); | 5162 ASSERT(innermost_function().raw() == signature_function.raw()); |
5372 innermost_function_ = Function::null(); | 5163 innermost_function_ = Function::null(); |
5373 | 5164 |
5374 if (FLAG_trace_parser) { | 5165 if (FLAG_trace_parser) { |
5375 OS::Print("TopLevel parsing function type alias '%s'\n", | 5166 OS::Print("TopLevel parsing function type alias '%s'\n", |
5376 String::Handle(Z, signature_function.Signature()).ToCString()); | 5167 String::Handle(Z, signature_function.Signature()).ToCString()); |
5377 } | 5168 } |
5378 // The alias should not be marked as finalized yet, since it needs to be | 5169 // The alias should not be marked as finalized yet, since it needs to be |
5379 // checked in the class finalizer for illegal self references. | 5170 // checked in the class finalizer for illegal self references. |
5380 ASSERT(!function_type_alias.is_finalized()); | 5171 ASSERT(!function_type_alias.is_finalized()); |
5381 pending_classes.Add(function_type_alias, Heap::kOld); | 5172 pending_classes.Add(function_type_alias, Heap::kOld); |
5382 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5173 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5383 library_.AddClassMetadata(function_type_alias, | 5174 library_.AddClassMetadata(function_type_alias, tl_owner, metadata_pos); |
5384 tl_owner, | |
5385 metadata_pos); | |
5386 } | 5175 } |
5387 } | 5176 } |
5388 | 5177 |
5389 | 5178 |
5390 // Consumes exactly one right angle bracket. If the current token is | 5179 // Consumes exactly one right angle bracket. If the current token is |
5391 // a single bracket token, it is consumed normally. However, if it is | 5180 // a single bracket token, it is consumed normally. However, if it is |
5392 // a double bracket, it is replaced by a single bracket token without | 5181 // a double bracket, it is replaced by a single bracket token without |
5393 // incrementing the token index. | 5182 // incrementing the token index. |
5394 void Parser::ConsumeRightAngleBracket() { | 5183 void Parser::ConsumeRightAngleBracket() { |
5395 if (token_kind_ == Token::kGT) { | 5184 if (token_kind_ == Token::kGT) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5510 // class finalizer. For now, ignore parsed bounds to avoid unresolved | 5299 // class finalizer. For now, ignore parsed bounds to avoid unresolved |
5511 // bounds while writing snapshots. | 5300 // bounds while writing snapshots. |
5512 type_parameter_bound = I->object_store()->object_type(); | 5301 type_parameter_bound = I->object_store()->object_type(); |
5513 } | 5302 } |
5514 } else { | 5303 } else { |
5515 type_parameter_bound = I->object_store()->object_type(); | 5304 type_parameter_bound = I->object_store()->object_type(); |
5516 } | 5305 } |
5517 type_parameter = TypeParameter::New( | 5306 type_parameter = TypeParameter::New( |
5518 parameterizing_class ? current_class() : Class::Handle(Z), | 5307 parameterizing_class ? current_class() : Class::Handle(Z), |
5519 parameterizing_class ? Function::Handle(Z) : innermost_function(), | 5308 parameterizing_class ? Function::Handle(Z) : innermost_function(), |
5520 index, | 5309 index, type_parameter_name, type_parameter_bound, declaration_pos); |
5521 type_parameter_name, | |
5522 type_parameter_bound, | |
5523 declaration_pos); | |
5524 if (!parameterizing_class) { | 5310 if (!parameterizing_class) { |
5525 // TODO(regis): Resolve and finalize function type parameter in | 5311 // TODO(regis): Resolve and finalize function type parameter in |
5526 // class finalizer. For now, already mark as finalized. | 5312 // class finalizer. For now, already mark as finalized. |
5527 type_parameter.SetIsFinalized(); | 5313 type_parameter.SetIsFinalized(); |
5528 } | 5314 } |
5529 type_parameters_array.Add( | 5315 type_parameters_array.Add( |
5530 &AbstractType::ZoneHandle(Z, type_parameter.raw())); | 5316 &AbstractType::ZoneHandle(Z, type_parameter.raw())); |
5531 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5317 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5532 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 5318 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
5533 } | 5319 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5634 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); | 5420 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); |
5635 } | 5421 } |
5636 if (mixin_type.IsTypeParameter()) { | 5422 if (mixin_type.IsTypeParameter()) { |
5637 ReportError(mixin_type.token_pos(), | 5423 ReportError(mixin_type.token_pos(), |
5638 "mixin type '%s' may not be a type parameter", | 5424 "mixin type '%s' may not be a type parameter", |
5639 String::Handle(Z, mixin_type.UserVisibleName()).ToCString()); | 5425 String::Handle(Z, mixin_type.UserVisibleName()).ToCString()); |
5640 } | 5426 } |
5641 mixin_types.Add(mixin_type); | 5427 mixin_types.Add(mixin_type); |
5642 } while (CurrentToken() == Token::kCOMMA); | 5428 } while (CurrentToken() == Token::kCOMMA); |
5643 return MixinAppType::New(super_type, | 5429 return MixinAppType::New(super_type, |
5644 Array::Handle(Z, Array::MakeArray(mixin_types))); | 5430 Array::Handle(Z, Array::MakeArray(mixin_types))); |
5645 } | 5431 } |
5646 | 5432 |
5647 | 5433 |
5648 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 5434 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
5649 const Object& owner, | 5435 const Object& owner, |
5650 TokenPosition metadata_pos) { | 5436 TokenPosition metadata_pos) { |
5651 TRACE_PARSER("ParseTopLevelVariable"); | 5437 TRACE_PARSER("ParseTopLevelVariable"); |
5652 const bool is_const = (CurrentToken() == Token::kCONST); | 5438 const bool is_const = (CurrentToken() == Token::kCONST); |
5653 // Const fields are implicitly final. | 5439 // Const fields are implicitly final. |
5654 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 5440 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
5655 const bool is_static = true; | 5441 const bool is_static = true; |
5656 const AbstractType& type = AbstractType::ZoneHandle(Z, | 5442 const AbstractType& type = AbstractType::ZoneHandle( |
5657 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 5443 Z, ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
5658 Field& field = Field::Handle(Z); | 5444 Field& field = Field::Handle(Z); |
5659 Function& getter = Function::Handle(Z); | 5445 Function& getter = Function::Handle(Z); |
5660 while (true) { | 5446 while (true) { |
5661 const TokenPosition name_pos = TokenPos(); | 5447 const TokenPosition name_pos = TokenPos(); |
5662 String& var_name = *ExpectIdentifier("variable name expected"); | 5448 String& var_name = *ExpectIdentifier("variable name expected"); |
5663 | 5449 |
5664 if (library_.LookupLocalObject(var_name) != Object::null()) { | 5450 if (library_.LookupLocalObject(var_name) != Object::null()) { |
5665 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); | 5451 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); |
5666 } | 5452 } |
5667 | 5453 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5699 if (LookaheadToken(1) == Token::kSEMICOLON) { | 5485 if (LookaheadToken(1) == Token::kSEMICOLON) { |
5700 has_simple_literal = IsSimpleLiteral(type, &field_value); | 5486 has_simple_literal = IsSimpleLiteral(type, &field_value); |
5701 } | 5487 } |
5702 SkipExpr(); | 5488 SkipExpr(); |
5703 field.SetStaticValue(field_value, true); | 5489 field.SetStaticValue(field_value, true); |
5704 field.set_has_initializer(true); | 5490 field.set_has_initializer(true); |
5705 | 5491 |
5706 if (!has_simple_literal) { | 5492 if (!has_simple_literal) { |
5707 // Create a static final getter. | 5493 // Create a static final getter. |
5708 String& getter_name = String::Handle(Z, Field::GetterSymbol(var_name)); | 5494 String& getter_name = String::Handle(Z, Field::GetterSymbol(var_name)); |
5709 getter = Function::New(getter_name, | 5495 getter = |
5710 RawFunction::kImplicitStaticFinalGetter, | 5496 Function::New(getter_name, RawFunction::kImplicitStaticFinalGetter, |
5711 is_static, | 5497 is_static, is_const, |
5712 is_const, | 5498 /* is_abstract = */ false, |
5713 /* is_abstract = */ false, | 5499 /* is_external = */ false, |
5714 /* is_external = */ false, | 5500 /* is_native = */ false, owner, name_pos); |
5715 /* is_native = */ false, | |
5716 owner, | |
5717 name_pos); | |
5718 getter.set_result_type(type); | 5501 getter.set_result_type(type); |
5719 getter.set_is_debuggable(false); | 5502 getter.set_is_debuggable(false); |
5720 getter.set_is_reflectable(is_reflectable); | 5503 getter.set_is_reflectable(is_reflectable); |
5721 top_level->AddFunction(getter); | 5504 top_level->AddFunction(getter); |
5722 } | 5505 } |
5723 } else if (is_final) { | 5506 } else if (is_final) { |
5724 ReportError(name_pos, "missing initializer for final or const variable"); | 5507 ReportError(name_pos, "missing initializer for final or const variable"); |
5725 } | 5508 } |
5726 | 5509 |
5727 if (CurrentToken() == Token::kCOMMA) { | 5510 if (CurrentToken() == Token::kCOMMA) { |
(...skipping 14 matching lines...) Expand all Loading... |
5742 if (CurrentToken() == Token::kMUL) { | 5525 if (CurrentToken() == Token::kMUL) { |
5743 const bool enableAsyncStar = true; | 5526 const bool enableAsyncStar = true; |
5744 if (!enableAsyncStar) { | 5527 if (!enableAsyncStar) { |
5745 ReportError("async* generator functions are not yet supported"); | 5528 ReportError("async* generator functions are not yet supported"); |
5746 } | 5529 } |
5747 ConsumeToken(); | 5530 ConsumeToken(); |
5748 return RawFunction::kAsyncGen; | 5531 return RawFunction::kAsyncGen; |
5749 } else { | 5532 } else { |
5750 return RawFunction::kAsync; | 5533 return RawFunction::kAsync; |
5751 } | 5534 } |
5752 } else if (IsSymbol(Symbols::Sync()) && | 5535 } else if (IsSymbol(Symbols::Sync()) && (LookaheadToken(1) == Token::kMUL)) { |
5753 (LookaheadToken(1) == Token::kMUL)) { | |
5754 const bool enableSyncStar = true; | 5536 const bool enableSyncStar = true; |
5755 if (!enableSyncStar) { | 5537 if (!enableSyncStar) { |
5756 ReportError("sync* generator functions are not yet supported"); | 5538 ReportError("sync* generator functions are not yet supported"); |
5757 } | 5539 } |
5758 ConsumeToken(); | 5540 ConsumeToken(); |
5759 ConsumeToken(); | 5541 ConsumeToken(); |
5760 return RawFunction::kSyncGen; | 5542 return RawFunction::kSyncGen; |
5761 } | 5543 } |
5762 return RawFunction::kNoModifier; | 5544 return RawFunction::kNoModifier; |
5763 } | 5545 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5800 func_name.ToCString()); | 5582 func_name.ToCString()); |
5801 } | 5583 } |
5802 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); | 5584 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); |
5803 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5585 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
5804 ReportError(name_pos, "'%s' is already defined as getter", | 5586 ReportError(name_pos, "'%s' is already defined as getter", |
5805 func_name.ToCString()); | 5587 func_name.ToCString()); |
5806 } | 5588 } |
5807 // A setter named x= may co-exist with a function named x, thus we do | 5589 // A setter named x= may co-exist with a function named x, thus we do |
5808 // not need to check setters. | 5590 // not need to check setters. |
5809 | 5591 |
5810 Function& func = Function::Handle(Z, | 5592 Function& func = Function::Handle( |
5811 Function::New(func_name, | 5593 Z, Function::New(func_name, RawFunction::kRegularFunction, |
5812 RawFunction::kRegularFunction, | 5594 /* is_static = */ true, |
5813 /* is_static = */ true, | 5595 /* is_const = */ false, |
5814 /* is_const = */ false, | 5596 /* is_abstract = */ false, is_external, |
5815 /* is_abstract = */ false, | 5597 /* is_native = */ false, // May change. |
5816 is_external, | 5598 owner, decl_begin_pos)); |
5817 /* is_native = */ false, // May change. | |
5818 owner, | |
5819 decl_begin_pos)); | |
5820 | 5599 |
5821 ASSERT(innermost_function().IsNull()); | 5600 ASSERT(innermost_function().IsNull()); |
5822 innermost_function_ = func.raw(); | 5601 innermost_function_ = func.raw(); |
5823 | 5602 |
5824 if (CurrentToken() == Token::kLT) { | 5603 if (CurrentToken() == Token::kLT) { |
5825 if (!FLAG_generic_method_syntax) { | 5604 if (!FLAG_generic_method_syntax) { |
5826 ReportError("generic functions not supported"); | 5605 ReportError("generic functions not supported"); |
5827 } | 5606 } |
5828 ParseTypeParameters(false); // Not parameterizing class, but function. | 5607 ParseTypeParameters(false); // Not parameterizing class, but function. |
5829 } | 5608 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5912 bool is_patch = false; | 5691 bool is_patch = false; |
5913 AbstractType& result_type = AbstractType::Handle(Z); | 5692 AbstractType& result_type = AbstractType::Handle(Z); |
5914 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 5693 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
5915 is_patch = true; | 5694 is_patch = true; |
5916 metadata_pos = TokenPosition::kNoSource; | 5695 metadata_pos = TokenPosition::kNoSource; |
5917 } else if (CurrentToken() == Token::kEXTERNAL) { | 5696 } else if (CurrentToken() == Token::kEXTERNAL) { |
5918 ConsumeToken(); | 5697 ConsumeToken(); |
5919 is_external = true; | 5698 is_external = true; |
5920 } | 5699 } |
5921 bool is_getter = (CurrentToken() == Token::kGET); | 5700 bool is_getter = (CurrentToken() == Token::kGET); |
5922 if (CurrentToken() == Token::kGET || | 5701 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
5923 CurrentToken() == Token::kSET) { | |
5924 ConsumeToken(); | 5702 ConsumeToken(); |
5925 result_type = Type::DynamicType(); | 5703 result_type = Type::DynamicType(); |
5926 } else { | 5704 } else { |
5927 if (CurrentToken() == Token::kVOID) { | 5705 if (CurrentToken() == Token::kVOID) { |
5928 ConsumeToken(); | 5706 ConsumeToken(); |
5929 result_type = Type::VoidType(); | 5707 result_type = Type::VoidType(); |
5930 } else { | 5708 } else { |
5931 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5709 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
5932 } | 5710 } |
5933 is_getter = (CurrentToken() == Token::kGET); | 5711 is_getter = (CurrentToken() == Token::kGET); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5972 // Check whether this setter conflicts with the implicit setter | 5750 // Check whether this setter conflicts with the implicit setter |
5973 // of a top-level variable with the same name. | 5751 // of a top-level variable with the same name. |
5974 if (!is_getter && | 5752 if (!is_getter && |
5975 (library_.LookupLocalField(*field_name) != Object::null())) { | 5753 (library_.LookupLocalField(*field_name) != Object::null())) { |
5976 ReportError(name_pos, "Variable '%s' is already defined in this library", | 5754 ReportError(name_pos, "Variable '%s' is already defined in this library", |
5977 field_name->ToCString()); | 5755 field_name->ToCString()); |
5978 } | 5756 } |
5979 bool found = library_.LookupLocalObject(accessor_name) != Object::null(); | 5757 bool found = library_.LookupLocalObject(accessor_name) != Object::null(); |
5980 if (found && !is_patch) { | 5758 if (found && !is_patch) { |
5981 ReportError(name_pos, "%s for '%s' is already defined", | 5759 ReportError(name_pos, "%s for '%s' is already defined", |
5982 is_getter ? "getter" : "setter", | 5760 is_getter ? "getter" : "setter", field_name->ToCString()); |
5983 field_name->ToCString()); | |
5984 } else if (!found && is_patch) { | 5761 } else if (!found && is_patch) { |
5985 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 5762 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
5986 is_getter ? "getter" : "setter", | 5763 is_getter ? "getter" : "setter", field_name->ToCString()); |
5987 field_name->ToCString()); | |
5988 } | 5764 } |
5989 | 5765 |
5990 const TokenPosition modifier_pos = TokenPos(); | 5766 const TokenPosition modifier_pos = TokenPos(); |
5991 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5767 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
5992 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { | 5768 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { |
5993 ReportError(modifier_pos, | 5769 ReportError(modifier_pos, |
5994 "setter function cannot be async, async* or sync*"); | 5770 "setter function cannot be async, async* or sync*"); |
5995 } | 5771 } |
5996 | 5772 |
5997 TokenPosition accessor_end_pos = accessor_pos; | 5773 TokenPosition accessor_end_pos = accessor_pos; |
(...skipping 18 matching lines...) Expand all Loading... |
6016 accessor_end_pos = TokenPos(); | 5792 accessor_end_pos = TokenPos(); |
6017 ExpectSemicolon(); | 5793 ExpectSemicolon(); |
6018 } else if (IsSymbol(Symbols::Native())) { | 5794 } else if (IsSymbol(Symbols::Native())) { |
6019 native_name = &ParseNativeDeclaration(); | 5795 native_name = &ParseNativeDeclaration(); |
6020 accessor_end_pos = TokenPos(); | 5796 accessor_end_pos = TokenPos(); |
6021 ExpectSemicolon(); | 5797 ExpectSemicolon(); |
6022 is_native = true; | 5798 is_native = true; |
6023 } else { | 5799 } else { |
6024 ReportError("function block expected"); | 5800 ReportError("function block expected"); |
6025 } | 5801 } |
6026 Function& func = Function::Handle(Z, | 5802 Function& func = Function::Handle( |
6027 Function::New(accessor_name, | 5803 Z, Function::New(accessor_name, is_getter ? RawFunction::kGetterFunction |
6028 is_getter ? RawFunction::kGetterFunction : | 5804 : RawFunction::kSetterFunction, |
6029 RawFunction::kSetterFunction, | 5805 is_static, |
6030 is_static, | 5806 /* is_const = */ false, |
6031 /* is_const = */ false, | 5807 /* is_abstract = */ false, is_external, is_native, owner, |
6032 /* is_abstract = */ false, | 5808 decl_begin_pos)); |
6033 is_external, | |
6034 is_native, | |
6035 owner, | |
6036 decl_begin_pos)); | |
6037 func.set_result_type(result_type); | 5809 func.set_result_type(result_type); |
6038 func.set_end_token_pos(accessor_end_pos); | 5810 func.set_end_token_pos(accessor_end_pos); |
6039 func.set_modifier(func_modifier); | 5811 func.set_modifier(func_modifier); |
6040 if (is_native) { | 5812 if (is_native) { |
6041 func.set_is_debuggable(false); | 5813 func.set_is_debuggable(false); |
6042 func.set_native_name(*native_name); | 5814 func.set_native_name(*native_name); |
6043 } | 5815 } |
6044 if (library_.is_dart_scheme() && library_.IsPrivate(accessor_name)) { | 5816 if (library_.is_dart_scheme() && library_.IsPrivate(accessor_name)) { |
6045 func.set_is_reflectable(false); | 5817 func.set_is_reflectable(false); |
6046 } | 5818 } |
6047 AddFormalParamsToFunction(¶ms, func); | 5819 AddFormalParamsToFunction(¶ms, func); |
6048 top_level->AddFunction(func); | 5820 top_level->AddFunction(func); |
6049 if (!is_patch) { | 5821 if (!is_patch) { |
6050 library_.AddObject(func, accessor_name); | 5822 library_.AddObject(func, accessor_name); |
6051 } else { | 5823 } else { |
6052 // Need to remove the previously added accessor that is being patched. | 5824 // Need to remove the previously added accessor that is being patched. |
6053 const Class& toplevel_cls = Class::Handle(Z, | 5825 const Class& toplevel_cls = Class::Handle( |
6054 owner.IsClass() ? Class::Cast(owner).raw() | 5826 Z, owner.IsClass() ? Class::Cast(owner).raw() |
6055 : PatchClass::Cast(owner).patched_class()); | 5827 : PatchClass::Cast(owner).patched_class()); |
6056 const Function& replaced_func = | 5828 const Function& replaced_func = |
6057 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); | 5829 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); |
6058 ASSERT(!replaced_func.IsNull()); | 5830 ASSERT(!replaced_func.IsNull()); |
6059 toplevel_cls.RemoveFunction(replaced_func); | 5831 toplevel_cls.RemoveFunction(replaced_func); |
6060 library_.ReplaceObject(func, accessor_name); | 5832 library_.ReplaceObject(func, accessor_name); |
6061 } | 5833 } |
6062 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5834 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
6063 library_.AddFunctionMetadata(func, metadata_pos); | 5835 library_.AddFunctionMetadata(func, metadata_pos); |
6064 } | 5836 } |
6065 } | 5837 } |
(...skipping 12 matching lines...) Expand all Loading... |
6078 } | 5850 } |
6079 ReportError(token_pos, "no library handler registered"); | 5851 ReportError(token_pos, "no library handler registered"); |
6080 } | 5852 } |
6081 // Block class finalization attempts when calling into the library | 5853 // Block class finalization attempts when calling into the library |
6082 // tag handler. | 5854 // tag handler. |
6083 I->BlockClassFinalization(); | 5855 I->BlockClassFinalization(); |
6084 Object& result = Object::Handle(Z); | 5856 Object& result = Object::Handle(Z); |
6085 { | 5857 { |
6086 TransitionVMToNative transition(T); | 5858 TransitionVMToNative transition(T); |
6087 Api::Scope api_scope(T); | 5859 Api::Scope api_scope(T); |
6088 Dart_Handle retval = handler(tag, | 5860 Dart_Handle retval = handler(tag, Api::NewHandle(T, library_.raw()), |
6089 Api::NewHandle(T, library_.raw()), | |
6090 Api::NewHandle(T, url.raw())); | 5861 Api::NewHandle(T, url.raw())); |
6091 result = Api::UnwrapHandle(retval); | 5862 result = Api::UnwrapHandle(retval); |
6092 } | 5863 } |
6093 I->UnblockClassFinalization(); | 5864 I->UnblockClassFinalization(); |
6094 if (result.IsError()) { | 5865 if (result.IsError()) { |
6095 // In case of an error we append an explanatory error message to the | 5866 // In case of an error we append an explanatory error message to the |
6096 // error obtained from the library tag handler. | 5867 // error obtained from the library tag handler. |
6097 const Error& prev_error = Error::Cast(result); | 5868 const Error& prev_error = Error::Cast(result); |
6098 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); | 5869 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); |
6099 } | 5870 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6178 AstNode* conditional_url_literal = ParseStringLiteral(false); | 5949 AstNode* conditional_url_literal = ParseStringLiteral(false); |
6179 | 5950 |
6180 // If there was already a condition that triggered, don't try to match | 5951 // If there was already a condition that triggered, don't try to match |
6181 // again. | 5952 // again. |
6182 if (condition_triggered) { | 5953 if (condition_triggered) { |
6183 continue; | 5954 continue; |
6184 } | 5955 } |
6185 // Check if this conditional line overrides the default import. | 5956 // Check if this conditional line overrides the default import. |
6186 const String& key = String::Handle( | 5957 const String& key = String::Handle( |
6187 String::ConcatAll(Array::Handle(Array::MakeArray(pieces)))); | 5958 String::ConcatAll(Array::Handle(Array::MakeArray(pieces)))); |
6188 const String& value = (valueNode == NULL) | 5959 const String& value = |
6189 ? Symbols::True() | 5960 (valueNode == NULL) |
6190 : String::Cast(valueNode->AsLiteralNode()->literal()); | 5961 ? Symbols::True() |
| 5962 : String::Cast(valueNode->AsLiteralNode()->literal()); |
6191 // Call the embedder to supply us with the environment. | 5963 // Call the embedder to supply us with the environment. |
6192 const String& env_value = | 5964 const String& env_value = |
6193 String::Handle(Api::GetEnvironmentValue(T, key)); | 5965 String::Handle(Api::GetEnvironmentValue(T, key)); |
6194 if (!env_value.IsNull() && env_value.Equals(value)) { | 5966 if (!env_value.IsNull() && env_value.Equals(value)) { |
6195 condition_triggered = true; | 5967 condition_triggered = true; |
6196 url_literal = conditional_url_literal; | 5968 url_literal = conditional_url_literal; |
6197 } | 5969 } |
6198 } | 5970 } |
6199 } | 5971 } |
6200 ASSERT(url_literal->IsLiteralNode()); | 5972 ASSERT(url_literal->IsLiteralNode()); |
(...skipping 11 matching lines...) Expand all Loading... |
6212 String& prefix = String::Handle(Z); | 5984 String& prefix = String::Handle(Z); |
6213 TokenPosition prefix_pos = TokenPosition::kNoSource; | 5985 TokenPosition prefix_pos = TokenPosition::kNoSource; |
6214 if (is_import && (CurrentToken() == Token::kAS)) { | 5986 if (is_import && (CurrentToken() == Token::kAS)) { |
6215 ConsumeToken(); | 5987 ConsumeToken(); |
6216 prefix_pos = TokenPos(); | 5988 prefix_pos = TokenPos(); |
6217 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 5989 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
6218 } | 5990 } |
6219 | 5991 |
6220 Array& show_names = Array::Handle(Z); | 5992 Array& show_names = Array::Handle(Z); |
6221 Array& hide_names = Array::Handle(Z); | 5993 Array& hide_names = Array::Handle(Z); |
6222 if (is_deferred_import || | 5994 if (is_deferred_import || IsSymbol(Symbols::Show()) || |
6223 IsSymbol(Symbols::Show()) || | |
6224 IsSymbol(Symbols::Hide())) { | 5995 IsSymbol(Symbols::Hide())) { |
6225 GrowableObjectArray& show_list = | 5996 GrowableObjectArray& show_list = |
6226 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 5997 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
6227 GrowableObjectArray& hide_list = | 5998 GrowableObjectArray& hide_list = |
6228 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 5999 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
6229 // Libraries imported through deferred import automatically hide | 6000 // Libraries imported through deferred import automatically hide |
6230 // the name 'loadLibrary'. | 6001 // the name 'loadLibrary'. |
6231 if (is_deferred_import) { | 6002 if (is_deferred_import) { |
6232 hide_list.Add(Symbols::LoadLibrary()); | 6003 hide_list.Add(Symbols::LoadLibrary()); |
6233 } | 6004 } |
(...skipping 30 matching lines...) Expand all Loading... |
6264 | 6035 |
6265 // If loading hasn't been requested yet, and if this is not a deferred | 6036 // If loading hasn't been requested yet, and if this is not a deferred |
6266 // library import, call the library tag handler to request loading | 6037 // library import, call the library tag handler to request loading |
6267 // the library. | 6038 // the library. |
6268 if (library.LoadNotStarted() && | 6039 if (library.LoadNotStarted() && |
6269 (!is_deferred_import || FLAG_load_deferred_eagerly)) { | 6040 (!is_deferred_import || FLAG_load_deferred_eagerly)) { |
6270 library.SetLoadRequested(); | 6041 library.SetLoadRequested(); |
6271 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); | 6042 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); |
6272 } | 6043 } |
6273 | 6044 |
6274 Namespace& ns = Namespace::Handle(Z, | 6045 Namespace& ns = |
6275 Namespace::New(library, show_names, hide_names)); | 6046 Namespace::Handle(Z, Namespace::New(library, show_names, hide_names)); |
6276 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 6047 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
6277 ns.AddMetadata(tl_owner, metadata_pos); | 6048 ns.AddMetadata(tl_owner, metadata_pos); |
6278 } | 6049 } |
6279 | 6050 |
6280 // Ensure that private dart:_ libraries are only imported into dart: | 6051 // Ensure that private dart:_ libraries are only imported into dart: |
6281 // libraries, including indirectly through exports. | 6052 // libraries, including indirectly through exports. |
6282 const String& lib_url = String::Handle(Z, library_.url()); | 6053 const String& lib_url = String::Handle(Z, library_.url()); |
6283 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 6054 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
6284 !lib_url.StartsWith(Symbols::DartScheme())) { | 6055 !lib_url.StartsWith(Symbols::DartScheme())) { |
6285 ReportError(import_pos, "private library is not accessible"); | 6056 ReportError(import_pos, "private library is not accessible"); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6362 ReportError("patch cannot override library name"); | 6133 ReportError("patch cannot override library name"); |
6363 } | 6134 } |
6364 ParseLibraryName(); | 6135 ParseLibraryName(); |
6365 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 6136 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
6366 library_.AddLibraryMetadata(tl_owner, metadata_pos); | 6137 library_.AddLibraryMetadata(tl_owner, metadata_pos); |
6367 } | 6138 } |
6368 rewind_pos = TokenPos(); | 6139 rewind_pos = TokenPos(); |
6369 metadata_pos = SkipMetadata(); | 6140 metadata_pos = SkipMetadata(); |
6370 } | 6141 } |
6371 while ((CurrentToken() == Token::kIMPORT) || | 6142 while ((CurrentToken() == Token::kIMPORT) || |
6372 (CurrentToken() == Token::kEXPORT)) { | 6143 (CurrentToken() == Token::kEXPORT)) { |
6373 ParseLibraryImportExport(tl_owner, metadata_pos); | 6144 ParseLibraryImportExport(tl_owner, metadata_pos); |
6374 rewind_pos = TokenPos(); | 6145 rewind_pos = TokenPos(); |
6375 metadata_pos = SkipMetadata(); | 6146 metadata_pos = SkipMetadata(); |
6376 } | 6147 } |
6377 // Core lib has not been explicitly imported, so we implicitly | 6148 // Core lib has not been explicitly imported, so we implicitly |
6378 // import it here. | 6149 // import it here. |
6379 if (!library_.ImportsCorelib()) { | 6150 if (!library_.ImportsCorelib()) { |
6380 Library& core_lib = Library::Handle(Z, Library::CoreLibrary()); | 6151 Library& core_lib = Library::Handle(Z, Library::CoreLibrary()); |
6381 ASSERT(!core_lib.IsNull()); | 6152 ASSERT(!core_lib.IsNull()); |
6382 const Namespace& core_ns = Namespace::Handle(Z, | 6153 const Namespace& core_ns = Namespace::Handle( |
| 6154 Z, |
6383 Namespace::New(core_lib, Object::null_array(), Object::null_array())); | 6155 Namespace::New(core_lib, Object::null_array(), Object::null_array())); |
6384 library_.AddImport(core_ns); | 6156 library_.AddImport(core_ns); |
6385 } | 6157 } |
6386 while (CurrentToken() == Token::kPART) { | 6158 while (CurrentToken() == Token::kPART) { |
6387 ParseLibraryPart(); | 6159 ParseLibraryPart(); |
6388 rewind_pos = TokenPos(); | 6160 rewind_pos = TokenPos(); |
6389 metadata_pos = SkipMetadata(); | 6161 metadata_pos = SkipMetadata(); |
6390 } | 6162 } |
6391 SetPosition(rewind_pos); | 6163 SetPosition(rewind_pos); |
6392 } | 6164 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6448 TokenPosition metadata_pos = SkipMetadata(); | 6220 TokenPosition metadata_pos = SkipMetadata(); |
6449 if (CurrentToken() == Token::kCLASS) { | 6221 if (CurrentToken() == Token::kCLASS) { |
6450 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); | 6222 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); |
6451 } else if (CurrentToken() == Token::kENUM) { | 6223 } else if (CurrentToken() == Token::kENUM) { |
6452 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); | 6224 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); |
6453 } else if ((CurrentToken() == Token::kTYPEDEF) && | 6225 } else if ((CurrentToken() == Token::kTYPEDEF) && |
6454 (LookaheadToken(1) != Token::kLPAREN)) { | 6226 (LookaheadToken(1) != Token::kLPAREN)) { |
6455 set_current_class(toplevel_class); | 6227 set_current_class(toplevel_class); |
6456 ParseTypedef(pending_classes, tl_owner, metadata_pos); | 6228 ParseTypedef(pending_classes, tl_owner, metadata_pos); |
6457 } else if ((CurrentToken() == Token::kABSTRACT) && | 6229 } else if ((CurrentToken() == Token::kABSTRACT) && |
6458 (LookaheadToken(1) == Token::kCLASS)) { | 6230 (LookaheadToken(1) == Token::kCLASS)) { |
6459 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); | 6231 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); |
6460 } else { | 6232 } else { |
6461 set_current_class(toplevel_class); | 6233 set_current_class(toplevel_class); |
6462 if (IsVariableDeclaration()) { | 6234 if (IsVariableDeclaration()) { |
6463 ParseTopLevelVariable(&top_level, tl_owner, metadata_pos); | 6235 ParseTopLevelVariable(&top_level, tl_owner, metadata_pos); |
6464 } else if (IsFunctionDeclaration()) { | 6236 } else if (IsFunctionDeclaration()) { |
6465 ParseTopLevelFunction(&top_level, tl_owner, metadata_pos); | 6237 ParseTopLevelFunction(&top_level, tl_owner, metadata_pos); |
6466 } else if (IsTopLevelAccessor()) { | 6238 } else if (IsTopLevelAccessor()) { |
6467 ParseTopLevelAccessor(&top_level, tl_owner, metadata_pos); | 6239 ParseTopLevelAccessor(&top_level, tl_owner, metadata_pos); |
6468 } else if (CurrentToken() == Token::kEOS) { | 6240 } else if (CurrentToken() == Token::kEOS) { |
(...skipping 23 matching lines...) Expand all Loading... |
6492 volatile uword c_stack_limit = | 6264 volatile uword c_stack_limit = |
6493 c_stack_base - OSThread::GetSpecifiedStackSize(); | 6265 c_stack_base - OSThread::GetSpecifiedStackSize(); |
6494 // Note: during early initialization the stack_base() can return 0. | 6266 // Note: during early initialization the stack_base() can return 0. |
6495 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { | 6267 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { |
6496 ReportError("stack overflow while parsing"); | 6268 ReportError("stack overflow while parsing"); |
6497 } | 6269 } |
6498 } | 6270 } |
6499 | 6271 |
6500 | 6272 |
6501 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 6273 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
6502 Block* block = new(Z) Block( | 6274 Block* block = new (Z) Block(current_block_, outer_scope, |
6503 current_block_, | 6275 new (Z) SequenceNode(TokenPos(), outer_scope)); |
6504 outer_scope, | |
6505 new(Z) SequenceNode(TokenPos(), outer_scope)); | |
6506 current_block_ = block; | 6276 current_block_ = block; |
6507 } | 6277 } |
6508 | 6278 |
6509 | 6279 |
6510 void Parser::OpenBlock() { | 6280 void Parser::OpenBlock() { |
6511 ASSERT(current_block_ != NULL); | 6281 ASSERT(current_block_ != NULL); |
6512 LocalScope* outer_scope = current_block_->scope; | 6282 LocalScope* outer_scope = current_block_->scope; |
6513 ChainNewBlock(new(Z) LocalScope( | 6283 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), |
6514 outer_scope, outer_scope->function_level(), outer_scope->loop_level())); | 6284 outer_scope->loop_level())); |
6515 } | 6285 } |
6516 | 6286 |
6517 | 6287 |
6518 void Parser::OpenLoopBlock() { | 6288 void Parser::OpenLoopBlock() { |
6519 ASSERT(current_block_ != NULL); | 6289 ASSERT(current_block_ != NULL); |
6520 LocalScope* outer_scope = current_block_->scope; | 6290 LocalScope* outer_scope = current_block_->scope; |
6521 ChainNewBlock(new(Z) LocalScope( | 6291 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), |
6522 outer_scope, | 6292 outer_scope->loop_level() + 1)); |
6523 outer_scope->function_level(), | |
6524 outer_scope->loop_level() + 1)); | |
6525 } | 6293 } |
6526 | 6294 |
6527 | 6295 |
6528 void Parser::OpenFunctionBlock(const Function& func) { | 6296 void Parser::OpenFunctionBlock(const Function& func) { |
6529 LocalScope* outer_scope; | 6297 LocalScope* outer_scope; |
6530 if (current_block_ == NULL) { | 6298 if (current_block_ == NULL) { |
6531 if (!func.IsLocalFunction()) { | 6299 if (!func.IsLocalFunction()) { |
6532 // We are compiling a non-nested function. | 6300 // We are compiling a non-nested function. |
6533 outer_scope = new(Z) LocalScope(NULL, 0, 0); | 6301 outer_scope = new (Z) LocalScope(NULL, 0, 0); |
6534 } else { | 6302 } else { |
6535 // We are compiling the function of an invoked closure. | 6303 // We are compiling the function of an invoked closure. |
6536 // Restore the outer scope containing all captured variables. | 6304 // Restore the outer scope containing all captured variables. |
6537 const ContextScope& context_scope = | 6305 const ContextScope& context_scope = |
6538 ContextScope::Handle(Z, func.context_scope()); | 6306 ContextScope::Handle(Z, func.context_scope()); |
6539 ASSERT(!context_scope.IsNull()); | 6307 ASSERT(!context_scope.IsNull()); |
6540 outer_scope = new(Z) LocalScope( | 6308 outer_scope = new (Z) |
6541 LocalScope::RestoreOuterScope(context_scope), 0, 0); | 6309 LocalScope(LocalScope::RestoreOuterScope(context_scope), 0, 0); |
6542 } | 6310 } |
6543 } else { | 6311 } else { |
6544 // We are parsing a nested function while compiling the enclosing function. | 6312 // We are parsing a nested function while compiling the enclosing function. |
6545 outer_scope = | 6313 outer_scope = new (Z) LocalScope( |
6546 new(Z) LocalScope(current_block_->scope, | 6314 current_block_->scope, current_block_->scope->function_level() + 1, 0); |
6547 current_block_->scope->function_level() + 1, | |
6548 0); | |
6549 } | 6315 } |
6550 ChainNewBlock(outer_scope); | 6316 ChainNewBlock(outer_scope); |
6551 } | 6317 } |
6552 | 6318 |
6553 | 6319 |
6554 void Parser::OpenAsyncClosure() { | 6320 void Parser::OpenAsyncClosure() { |
6555 TRACE_PARSER("OpenAsyncClosure"); | 6321 TRACE_PARSER("OpenAsyncClosure"); |
6556 async_temp_scope_ = current_block_->scope; | 6322 async_temp_scope_ = current_block_->scope; |
6557 OpenAsyncTryBlock(); | 6323 OpenAsyncTryBlock(); |
6558 } | 6324 } |
6559 | 6325 |
6560 | 6326 |
6561 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { | 6327 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode* body) { |
6562 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); | 6328 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); |
6563 // The generated try-catch-finally that wraps the async generator function | 6329 // The generated try-catch-finally that wraps the async generator function |
6564 // body is the outermost try statement. | 6330 // body is the outermost try statement. |
6565 ASSERT(try_stack_ != NULL); | 6331 ASSERT(try_stack_ != NULL); |
6566 ASSERT(try_stack_->outer_try() == NULL); | 6332 ASSERT(try_stack_->outer_try() == NULL); |
6567 // We only get here when parsing an async generator body. | 6333 // We only get here when parsing an async generator body. |
6568 ASSERT(innermost_function().IsAsyncGenClosure()); | 6334 ASSERT(innermost_function().IsAsyncGenClosure()); |
6569 | 6335 |
6570 const TokenPosition try_end_pos = innermost_function().end_token_pos(); | 6336 const TokenPosition try_end_pos = innermost_function().end_token_pos(); |
6571 | 6337 |
6572 // The try-block (closure body code) has been parsed. We are now | 6338 // The try-block (closure body code) has been parsed. We are now |
6573 // generating the code for the catch block. | 6339 // generating the code for the catch block. |
6574 LocalScope* try_scope = current_block_->scope; | 6340 LocalScope* try_scope = current_block_->scope; |
6575 try_stack_->enter_catch(); | 6341 try_stack_->enter_catch(); |
6576 OpenBlock(); // Catch handler list. | 6342 OpenBlock(); // Catch handler list. |
6577 OpenBlock(); // Catch block. | 6343 OpenBlock(); // Catch block. |
6578 | 6344 |
6579 // Add the exception and stack trace parameters to the scope. | 6345 // Add the exception and stack trace parameters to the scope. |
6580 CatchParamDesc exception_param; | 6346 CatchParamDesc exception_param; |
6581 CatchParamDesc stack_trace_param; | 6347 CatchParamDesc stack_trace_param; |
6582 exception_param.token_pos = TokenPosition::kNoSource; | 6348 exception_param.token_pos = TokenPosition::kNoSource; |
6583 exception_param.type = &Object::dynamic_type(); | 6349 exception_param.type = &Object::dynamic_type(); |
6584 exception_param.name = &Symbols::ExceptionParameter(); | 6350 exception_param.name = &Symbols::ExceptionParameter(); |
6585 stack_trace_param.token_pos = TokenPosition::kNoSource; | 6351 stack_trace_param.token_pos = TokenPosition::kNoSource; |
6586 stack_trace_param.type = &Object::dynamic_type(); | 6352 stack_trace_param.type = &Object::dynamic_type(); |
6587 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6353 stack_trace_param.name = &Symbols::StackTraceParameter(); |
6588 | 6354 |
6589 AddCatchParamsToScope( | 6355 AddCatchParamsToScope(&exception_param, &stack_trace_param, |
6590 &exception_param, &stack_trace_param, current_block_->scope); | 6356 current_block_->scope); |
6591 | 6357 |
6592 // Generate code to save the exception object and stack trace | 6358 // Generate code to save the exception object and stack trace |
6593 // in local variables. | 6359 // in local variables. |
6594 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6360 LocalVariable* context_var = |
6595 Symbols::SavedTryContextVar()); | 6361 try_scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
6596 ASSERT(context_var != NULL); | 6362 ASSERT(context_var != NULL); |
6597 | 6363 |
6598 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6364 LocalVariable* exception_var = |
6599 Symbols::ExceptionVar()); | 6365 try_scope->LocalLookupVariable(Symbols::ExceptionVar()); |
6600 ASSERT(exception_var != NULL); | 6366 ASSERT(exception_var != NULL); |
6601 if (exception_param.var != NULL) { | 6367 if (exception_param.var != NULL) { |
6602 // Generate code to load the exception object (:exception_var) into | 6368 // Generate code to load the exception object (:exception_var) into |
6603 // the exception variable specified in this block. | 6369 // the exception variable specified in this block. |
6604 current_block_->statements->Add(new(Z) StoreLocalNode( | 6370 current_block_->statements->Add(new (Z) StoreLocalNode( |
6605 TokenPosition::kNoSource, | 6371 TokenPosition::kNoSource, exception_param.var, |
6606 exception_param.var, | 6372 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
6607 new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); | |
6608 } | 6373 } |
6609 | 6374 |
6610 LocalVariable* stack_trace_var = | 6375 LocalVariable* stack_trace_var = |
6611 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6376 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
6612 ASSERT(stack_trace_var != NULL); | 6377 ASSERT(stack_trace_var != NULL); |
6613 if (stack_trace_param.var != NULL) { | 6378 if (stack_trace_param.var != NULL) { |
6614 // A stack trace variable is specified in this block, so generate code | 6379 // A stack trace variable is specified in this block, so generate code |
6615 // to load the stack trace object (:stack_trace_var) into the stack | 6380 // to load the stack trace object (:stack_trace_var) into the stack |
6616 // trace variable specified in this block. | 6381 // trace variable specified in this block. |
6617 current_block_->statements->Add(new(Z) StoreLocalNode( | 6382 current_block_->statements->Add(new (Z) StoreLocalNode( |
6618 TokenPosition::kNoSource, | 6383 TokenPosition::kNoSource, stack_trace_param.var, |
6619 stack_trace_param.var, | 6384 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
6620 new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); | |
6621 } | 6385 } |
6622 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6386 LocalVariable* saved_exception_var = |
6623 Symbols::SavedExceptionVar()); | 6387 try_scope->LocalLookupVariable(Symbols::SavedExceptionVar()); |
6624 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6388 LocalVariable* saved_stack_trace_var = |
6625 Symbols::SavedStackTraceVar()); | 6389 try_scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); |
6626 SaveExceptionAndStacktrace(current_block_->statements, | 6390 SaveExceptionAndStacktrace(current_block_->statements, exception_var, |
6627 exception_var, | 6391 stack_trace_var, saved_exception_var, |
6628 stack_trace_var, | |
6629 saved_exception_var, | |
6630 saved_stack_trace_var); | 6392 saved_stack_trace_var); |
6631 | 6393 |
6632 // Catch block: add the error to the stream. | 6394 // Catch block: add the error to the stream. |
6633 // :controller.AddError(:exception, :stack_trace); | 6395 // :controller.AddError(:exception, :stack_trace); |
6634 // return; // The finally block will close the stream. | 6396 // return; // The finally block will close the stream. |
6635 LocalVariable* controller = | 6397 LocalVariable* controller = |
6636 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6398 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
6637 ASSERT(controller != NULL); | 6399 ASSERT(controller != NULL); |
6638 ArgumentListNode* args = | 6400 ArgumentListNode* args = new (Z) ArgumentListNode(TokenPosition::kNoSource); |
6639 new(Z) ArgumentListNode(TokenPosition::kNoSource); | 6401 args->Add(new (Z) |
6640 args->Add(new(Z) LoadLocalNode( | 6402 LoadLocalNode(TokenPosition::kNoSource, exception_param.var)); |
6641 TokenPosition::kNoSource, exception_param.var)); | 6403 args->Add(new (Z) |
6642 args->Add(new(Z) LoadLocalNode( | 6404 LoadLocalNode(TokenPosition::kNoSource, stack_trace_param.var)); |
6643 TokenPosition::kNoSource, stack_trace_param.var)); | 6405 current_block_->statements->Add(new (Z) InstanceCallNode( |
6644 current_block_->statements->Add( | 6406 try_end_pos, new (Z) LoadLocalNode(TokenPosition::kNoSource, controller), |
6645 new(Z) InstanceCallNode(try_end_pos, | 6407 Symbols::AddError(), args)); |
6646 new(Z) LoadLocalNode(TokenPosition::kNoSource, controller), | 6408 ReturnNode* return_node = new (Z) ReturnNode(TokenPosition::kNoSource); |
6647 Symbols::AddError(), | |
6648 args)); | |
6649 ReturnNode* return_node = new(Z) ReturnNode(TokenPosition::kNoSource); | |
6650 AddNodeForFinallyInlining(return_node); | 6409 AddNodeForFinallyInlining(return_node); |
6651 current_block_->statements->Add(return_node); | 6410 current_block_->statements->Add(return_node); |
6652 AstNode* catch_block = CloseBlock(); | 6411 AstNode* catch_block = CloseBlock(); |
6653 current_block_->statements->Add(catch_block); | 6412 current_block_->statements->Add(catch_block); |
6654 SequenceNode* catch_handler_list = CloseBlock(); | 6413 SequenceNode* catch_handler_list = CloseBlock(); |
6655 | 6414 |
6656 TryStack* try_statement = PopTry(); | 6415 TryStack* try_statement = PopTry(); |
6657 ASSERT(try_stack_ == NULL); // We popped the outermost try block. | 6416 ASSERT(try_stack_ == NULL); // We popped the outermost try block. |
6658 | 6417 |
6659 // Finally block: closing the stream and returning. Instead of simply | 6418 // Finally block: closing the stream and returning. Instead of simply |
6660 // returning, create an await state and suspend. There may be outstanding | 6419 // returning, create an await state and suspend. There may be outstanding |
6661 // calls to schedule the generator body. This suspension ensures that we | 6420 // calls to schedule the generator body. This suspension ensures that we |
6662 // do not repeat any code of the generator body. | 6421 // do not repeat any code of the generator body. |
6663 // :controller.close(); | 6422 // :controller.close(); |
6664 // suspend; | 6423 // suspend; |
6665 // We need to inline this code in all recorded exit points. | 6424 // We need to inline this code in all recorded exit points. |
6666 intptr_t node_index = 0; | 6425 intptr_t node_index = 0; |
6667 SequenceNode* finally_clause = NULL; | 6426 SequenceNode* finally_clause = NULL; |
6668 if (try_stack_ != NULL) { | 6427 if (try_stack_ != NULL) { |
6669 try_stack_->enter_finally(); | 6428 try_stack_->enter_finally(); |
6670 } | 6429 } |
6671 do { | 6430 do { |
6672 OpenBlock(); | 6431 OpenBlock(); |
6673 ArgumentListNode* no_args = | 6432 ArgumentListNode* no_args = |
6674 new(Z) ArgumentListNode(TokenPosition::kNoSource); | 6433 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
6675 current_block_->statements->Add( | 6434 current_block_->statements->Add(new (Z) InstanceCallNode( |
6676 new(Z) InstanceCallNode(try_end_pos, | 6435 try_end_pos, |
6677 new(Z) LoadLocalNode(TokenPosition::kNoSource, controller), | 6436 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller), |
6678 Symbols::Close(), | 6437 Symbols::Close(), no_args)); |
6679 no_args)); | |
6680 | 6438 |
6681 // Suspend after the close. | 6439 // Suspend after the close. |
6682 AwaitMarkerNode* await_marker = | 6440 AwaitMarkerNode* await_marker = new (Z) AwaitMarkerNode( |
6683 new(Z) AwaitMarkerNode(async_temp_scope_, | 6441 async_temp_scope_, current_block_->scope, TokenPosition::kNoSource); |
6684 current_block_->scope, | |
6685 TokenPosition::kNoSource); | |
6686 current_block_->statements->Add(await_marker); | 6442 current_block_->statements->Add(await_marker); |
6687 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); | 6443 ReturnNode* continuation_ret = new (Z) ReturnNode(try_end_pos); |
6688 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); | 6444 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); |
6689 current_block_->statements->Add(continuation_ret); | 6445 current_block_->statements->Add(continuation_ret); |
6690 | 6446 |
6691 finally_clause = CloseBlock(); | 6447 finally_clause = CloseBlock(); |
6692 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 6448 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
6693 if (node_to_inline != NULL) { | 6449 if (node_to_inline != NULL) { |
6694 InlinedFinallyNode* node = | 6450 InlinedFinallyNode* node = |
6695 new(Z) InlinedFinallyNode(try_end_pos, | 6451 new (Z) InlinedFinallyNode(try_end_pos, finally_clause, context_var, |
6696 finally_clause, | 6452 // No outer try statement |
6697 context_var, | 6453 CatchClauseNode::kInvalidTryIndex); |
6698 // No outer try statement | |
6699 CatchClauseNode::kInvalidTryIndex); | |
6700 finally_clause = NULL; | 6454 finally_clause = NULL; |
6701 AddFinallyClauseToNode(true, node_to_inline, node); | 6455 AddFinallyClauseToNode(true, node_to_inline, node); |
6702 node_index++; | 6456 node_index++; |
6703 } | 6457 } |
6704 } while (finally_clause == NULL); | 6458 } while (finally_clause == NULL); |
6705 | 6459 |
6706 if (try_stack_ != NULL) { | 6460 if (try_stack_ != NULL) { |
6707 try_stack_->exit_finally(); | 6461 try_stack_->exit_finally(); |
6708 } | 6462 } |
6709 | 6463 |
6710 const GrowableObjectArray& handler_types = | 6464 const GrowableObjectArray& handler_types = |
6711 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6465 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
6712 // Catch block handles all exceptions. | 6466 // Catch block handles all exceptions. |
6713 handler_types.Add(Object::dynamic_type()); | 6467 handler_types.Add(Object::dynamic_type()); |
6714 | 6468 |
6715 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 6469 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
6716 TokenPosition::kNoSource, | 6470 TokenPosition::kNoSource, catch_handler_list, |
6717 catch_handler_list, | 6471 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), context_var, |
6718 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6472 exception_var, stack_trace_var, saved_exception_var, |
6719 context_var, | 6473 saved_stack_trace_var, AllocateTryIndex(), true); |
6720 exception_var, | |
6721 stack_trace_var, | |
6722 saved_exception_var, | |
6723 saved_stack_trace_var, | |
6724 AllocateTryIndex(), | |
6725 true); | |
6726 | 6474 |
6727 const intptr_t try_index = try_statement->try_index(); | 6475 const intptr_t try_index = try_statement->try_index(); |
6728 | 6476 |
6729 AstNode* try_catch_node = | 6477 AstNode* try_catch_node = new (Z) |
6730 new(Z) TryCatchNode(TokenPosition::kNoSource, | 6478 TryCatchNode(TokenPosition::kNoSource, body, context_var, catch_clause, |
6731 body, | 6479 finally_clause, try_index, finally_clause); |
6732 context_var, | |
6733 catch_clause, | |
6734 finally_clause, | |
6735 try_index, | |
6736 finally_clause); | |
6737 current_block_->statements->Add(try_catch_node); | 6480 current_block_->statements->Add(try_catch_node); |
6738 return CloseBlock(); | 6481 return CloseBlock(); |
6739 } | 6482 } |
6740 | 6483 |
6741 | 6484 |
6742 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | 6485 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { |
6743 // This is the outermost try-catch of the function. | 6486 // This is the outermost try-catch of the function. |
6744 ASSERT(try_stack_ != NULL); | 6487 ASSERT(try_stack_ != NULL); |
6745 ASSERT(try_stack_->outer_try() == NULL); | 6488 ASSERT(try_stack_->outer_try() == NULL); |
6746 ASSERT(innermost_function().IsAsyncClosure()); | 6489 ASSERT(innermost_function().IsAsyncClosure()); |
6747 LocalScope* try_scope = current_block_->scope; | 6490 LocalScope* try_scope = current_block_->scope; |
6748 | 6491 |
6749 try_stack_->enter_catch(); | 6492 try_stack_->enter_catch(); |
6750 | 6493 |
6751 OpenBlock(); // Catch handler list. | 6494 OpenBlock(); // Catch handler list. |
6752 OpenBlock(); // Catch block. | 6495 OpenBlock(); // Catch block. |
6753 CatchParamDesc exception_param; | 6496 CatchParamDesc exception_param; |
6754 CatchParamDesc stack_trace_param; | 6497 CatchParamDesc stack_trace_param; |
6755 exception_param.token_pos = TokenPosition::kNoSource; | 6498 exception_param.token_pos = TokenPosition::kNoSource; |
6756 exception_param.type = &Object::dynamic_type(); | 6499 exception_param.type = &Object::dynamic_type(); |
6757 exception_param.name = &Symbols::ExceptionParameter(); | 6500 exception_param.name = &Symbols::ExceptionParameter(); |
6758 stack_trace_param.token_pos = TokenPosition::kNoSource; | 6501 stack_trace_param.token_pos = TokenPosition::kNoSource; |
6759 stack_trace_param.type = &Object::dynamic_type(); | 6502 stack_trace_param.type = &Object::dynamic_type(); |
6760 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6503 stack_trace_param.name = &Symbols::StackTraceParameter(); |
6761 | 6504 |
6762 AddCatchParamsToScope( | 6505 AddCatchParamsToScope(&exception_param, &stack_trace_param, |
6763 &exception_param, &stack_trace_param, current_block_->scope); | 6506 current_block_->scope); |
6764 | 6507 |
6765 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6508 LocalVariable* context_var = |
6766 Symbols::SavedTryContextVar()); | 6509 try_scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
6767 ASSERT(context_var != NULL); | 6510 ASSERT(context_var != NULL); |
6768 | 6511 |
6769 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6512 LocalVariable* exception_var = |
6770 Symbols::ExceptionVar()); | 6513 try_scope->LocalLookupVariable(Symbols::ExceptionVar()); |
6771 if (exception_param.var != NULL) { | 6514 if (exception_param.var != NULL) { |
6772 // Generate code to load the exception object (:exception_var) into | 6515 // Generate code to load the exception object (:exception_var) into |
6773 // the exception variable specified in this block. | 6516 // the exception variable specified in this block. |
6774 ASSERT(exception_var != NULL); | 6517 ASSERT(exception_var != NULL); |
6775 current_block_->statements->Add(new(Z) StoreLocalNode( | 6518 current_block_->statements->Add(new (Z) StoreLocalNode( |
6776 TokenPosition::kNoSource, | 6519 TokenPosition::kNoSource, exception_param.var, |
6777 exception_param.var, | 6520 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
6778 new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); | |
6779 } | 6521 } |
6780 | 6522 |
6781 LocalVariable* stack_trace_var = | 6523 LocalVariable* stack_trace_var = |
6782 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6524 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
6783 if (stack_trace_param.var != NULL) { | 6525 if (stack_trace_param.var != NULL) { |
6784 // A stack trace variable is specified in this block, so generate code | 6526 // A stack trace variable is specified in this block, so generate code |
6785 // to load the stack trace object (:stack_trace_var) into the stack | 6527 // to load the stack trace object (:stack_trace_var) into the stack |
6786 // trace variable specified in this block. | 6528 // trace variable specified in this block. |
6787 ASSERT(stack_trace_var != NULL); | 6529 ASSERT(stack_trace_var != NULL); |
6788 current_block_->statements->Add(new(Z) StoreLocalNode( | 6530 current_block_->statements->Add(new (Z) StoreLocalNode( |
6789 TokenPosition::kNoSource, | 6531 TokenPosition::kNoSource, stack_trace_param.var, |
6790 stack_trace_param.var, | 6532 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
6791 new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); | |
6792 } | 6533 } |
6793 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6534 LocalVariable* saved_exception_var = |
6794 Symbols::SavedExceptionVar()); | 6535 try_scope->LocalLookupVariable(Symbols::SavedExceptionVar()); |
6795 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6536 LocalVariable* saved_stack_trace_var = |
6796 Symbols::SavedStackTraceVar()); | 6537 try_scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); |
6797 SaveExceptionAndStacktrace(current_block_->statements, | 6538 SaveExceptionAndStacktrace(current_block_->statements, exception_var, |
6798 exception_var, | 6539 stack_trace_var, saved_exception_var, |
6799 stack_trace_var, | |
6800 saved_exception_var, | |
6801 saved_stack_trace_var); | 6540 saved_stack_trace_var); |
6802 | 6541 |
6803 // Complete the async future with an error. This catch block executes | 6542 // Complete the async future with an error. This catch block executes |
6804 // unconditionally, there is no need to generate a type check for. | 6543 // unconditionally, there is no need to generate a type check for. |
6805 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 6544 LocalVariable* async_completer = |
6806 Symbols::AsyncCompleter(), false); | 6545 current_block_->scope->LookupVariable(Symbols::AsyncCompleter(), false); |
6807 ASSERT(async_completer != NULL); | 6546 ASSERT(async_completer != NULL); |
6808 ArgumentListNode* completer_args = | 6547 ArgumentListNode* completer_args = |
6809 new (Z) ArgumentListNode(TokenPosition::kNoSource); | 6548 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
6810 completer_args->Add( | 6549 completer_args->Add( |
6811 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_param.var)); | 6550 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_param.var)); |
6812 completer_args->Add( | 6551 completer_args->Add( |
6813 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 6552 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_param.var)); |
6814 stack_trace_param.var)); | |
6815 current_block_->statements->Add(new (Z) InstanceCallNode( | 6553 current_block_->statements->Add(new (Z) InstanceCallNode( |
6816 TokenPos(), | 6554 TokenPos(), |
6817 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_completer), | 6555 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_completer), |
6818 Symbols::CompleterCompleteError(), | 6556 Symbols::CompleterCompleteError(), completer_args)); |
6819 completer_args)); | |
6820 ReturnNode* return_node = new (Z) ReturnNode(TokenPosition::kNoSource); | 6557 ReturnNode* return_node = new (Z) ReturnNode(TokenPosition::kNoSource); |
6821 // Behavior like a continuation return, i.e,. don't call a completer. | 6558 // Behavior like a continuation return, i.e,. don't call a completer. |
6822 return_node->set_return_type(ReturnNode::kContinuation); | 6559 return_node->set_return_type(ReturnNode::kContinuation); |
6823 current_block_->statements->Add(return_node); | 6560 current_block_->statements->Add(return_node); |
6824 AstNode* catch_block = CloseBlock(); | 6561 AstNode* catch_block = CloseBlock(); |
6825 current_block_->statements->Add(catch_block); | 6562 current_block_->statements->Add(catch_block); |
6826 SequenceNode* catch_handler_list = CloseBlock(); | 6563 SequenceNode* catch_handler_list = CloseBlock(); |
6827 | 6564 |
6828 const GrowableObjectArray& handler_types = | 6565 const GrowableObjectArray& handler_types = |
6829 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6566 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
6830 handler_types.SetLength(0); | 6567 handler_types.SetLength(0); |
6831 handler_types.Add(*exception_param.type); | 6568 handler_types.Add(*exception_param.type); |
6832 | 6569 |
6833 TryStack* try_statement = PopTry(); | 6570 TryStack* try_statement = PopTry(); |
6834 const intptr_t try_index = try_statement->try_index(); | 6571 const intptr_t try_index = try_statement->try_index(); |
6835 | 6572 |
6836 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( | 6573 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
6837 TokenPosition::kNoSource, | 6574 TokenPosition::kNoSource, catch_handler_list, |
6838 catch_handler_list, | 6575 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), context_var, |
6839 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6576 exception_var, stack_trace_var, saved_exception_var, |
6840 context_var, | 6577 saved_stack_trace_var, CatchClauseNode::kInvalidTryIndex, true); |
6841 exception_var, | |
6842 stack_trace_var, | |
6843 saved_exception_var, | |
6844 saved_stack_trace_var, | |
6845 CatchClauseNode::kInvalidTryIndex, | |
6846 true); | |
6847 AstNode* try_catch_node = new (Z) TryCatchNode( | 6578 AstNode* try_catch_node = new (Z) TryCatchNode( |
6848 TokenPosition::kNoSource, | 6579 TokenPosition::kNoSource, try_block, context_var, catch_clause, |
6849 try_block, | |
6850 context_var, | |
6851 catch_clause, | |
6852 NULL, // No finally clause. | 6580 NULL, // No finally clause. |
6853 try_index, | 6581 try_index, |
6854 NULL); // No rethrow-finally clause. | 6582 NULL); // No rethrow-finally clause. |
6855 current_block_->statements->Add(try_catch_node); | 6583 current_block_->statements->Add(try_catch_node); |
6856 return CloseBlock(); | 6584 return CloseBlock(); |
6857 } | 6585 } |
6858 | 6586 |
6859 | 6587 |
6860 // Wrap the body of the async or async* closure in a try/catch block. | 6588 // Wrap the body of the async or async* closure in a try/catch block. |
6861 void Parser::OpenAsyncTryBlock() { | 6589 void Parser::OpenAsyncTryBlock() { |
6862 ASSERT(innermost_function().IsAsyncClosure() || | 6590 ASSERT(innermost_function().IsAsyncClosure() || |
6863 innermost_function().IsAsyncGenClosure()); | 6591 innermost_function().IsAsyncGenClosure()); |
6864 LocalVariable* context_var = NULL; | 6592 LocalVariable* context_var = NULL; |
6865 LocalVariable* exception_var = NULL; | 6593 LocalVariable* exception_var = NULL; |
6866 LocalVariable* stack_trace_var = NULL; | 6594 LocalVariable* stack_trace_var = NULL; |
6867 LocalVariable* saved_exception_var = NULL; | 6595 LocalVariable* saved_exception_var = NULL; |
6868 LocalVariable* saved_stack_trace_var = NULL; | 6596 LocalVariable* saved_stack_trace_var = NULL; |
6869 SetupExceptionVariables(current_block_->scope, | 6597 SetupExceptionVariables(current_block_->scope, true, &context_var, |
6870 true, | 6598 &exception_var, &stack_trace_var, |
6871 &context_var, | 6599 &saved_exception_var, &saved_stack_trace_var); |
6872 &exception_var, | |
6873 &stack_trace_var, | |
6874 &saved_exception_var, | |
6875 &saved_stack_trace_var); | |
6876 | 6600 |
6877 // Open the try block. | 6601 // Open the try block. |
6878 OpenBlock(); | 6602 OpenBlock(); |
6879 // This is the outermost try-catch in the function. | 6603 // This is the outermost try-catch in the function. |
6880 ASSERT(try_stack_ == NULL); | 6604 ASSERT(try_stack_ == NULL); |
6881 PushTry(current_block_); | 6605 PushTry(current_block_); |
6882 | 6606 |
6883 SetupSavedTryContext(context_var); | 6607 SetupSavedTryContext(context_var); |
6884 } | 6608 } |
6885 | 6609 |
6886 | 6610 |
6887 void Parser::AddSyncGenClosureParameters(ParamList* params) { | 6611 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
6888 // Create the parameter list for the body closure of a sync generator: | 6612 // Create the parameter list for the body closure of a sync generator: |
6889 // 1) Implicit closure parameter; | 6613 // 1) Implicit closure parameter; |
6890 // 2) Iterator | 6614 // 2) Iterator |
6891 // Add implicit closure parameter if not already present. | 6615 // Add implicit closure parameter if not already present. |
6892 if (params->parameters->length() == 0) { | 6616 if (params->parameters->length() == 0) { |
6893 params->AddFinalParameter( | 6617 params->AddFinalParameter(TokenPosition::kMinSource, |
6894 TokenPosition::kMinSource, | 6618 &Symbols::ClosureParameter(), |
6895 &Symbols::ClosureParameter(), | 6619 &Object::dynamic_type()); |
6896 &Object::dynamic_type()); | |
6897 } | 6620 } |
6898 ParamDesc iterator_param; | 6621 ParamDesc iterator_param; |
6899 iterator_param.name = &Symbols::IteratorParameter(); | 6622 iterator_param.name = &Symbols::IteratorParameter(); |
6900 iterator_param.type = &Object::dynamic_type(); | 6623 iterator_param.type = &Object::dynamic_type(); |
6901 params->parameters->Add(iterator_param); | 6624 params->parameters->Add(iterator_param); |
6902 params->num_fixed_parameters++; | 6625 params->num_fixed_parameters++; |
6903 } | 6626 } |
6904 | 6627 |
6905 | 6628 |
6906 void Parser::AddAsyncGenClosureParameters(ParamList* params) { | 6629 void Parser::AddAsyncGenClosureParameters(ParamList* params) { |
(...skipping 17 matching lines...) Expand all Loading... |
6924 Z, I->LookupClosureFunction(innermost_function(), func_pos)); | 6647 Z, I->LookupClosureFunction(innermost_function(), func_pos)); |
6925 if (!found_func.IsNull()) { | 6648 if (!found_func.IsNull()) { |
6926 ASSERT(found_func.IsSyncGenClosure()); | 6649 ASSERT(found_func.IsSyncGenClosure()); |
6927 body = found_func.raw(); | 6650 body = found_func.raw(); |
6928 body_closure_name = body.name(); | 6651 body_closure_name = body.name(); |
6929 } else { | 6652 } else { |
6930 // Create the closure containing the body of this generator function. | 6653 // Create the closure containing the body of this generator function. |
6931 String& generator_name = String::Handle(Z, innermost_function().name()); | 6654 String& generator_name = String::Handle(Z, innermost_function().name()); |
6932 body_closure_name = | 6655 body_closure_name = |
6933 Symbols::NewFormatted(T, "<%s_sync_body>", generator_name.ToCString()); | 6656 Symbols::NewFormatted(T, "<%s_sync_body>", generator_name.ToCString()); |
6934 body = Function::NewClosureFunction(body_closure_name, | 6657 body = Function::NewClosureFunction(body_closure_name, innermost_function(), |
6935 innermost_function(), | |
6936 func_pos); | 6658 func_pos); |
6937 body.set_is_generated_body(true); | 6659 body.set_is_generated_body(true); |
6938 body.set_result_type(Object::dynamic_type()); | 6660 body.set_result_type(Object::dynamic_type()); |
6939 is_new_closure = true; | 6661 is_new_closure = true; |
6940 } | 6662 } |
6941 | 6663 |
6942 ParamList closure_params; | 6664 ParamList closure_params; |
6943 AddSyncGenClosureParameters(&closure_params); | 6665 AddSyncGenClosureParameters(&closure_params); |
6944 | 6666 |
6945 if (is_new_closure) { | 6667 if (is_new_closure) { |
(...skipping 22 matching lines...) Expand all Loading... |
6968 LocalVariable* existing_var = | 6690 LocalVariable* existing_var = |
6969 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 6691 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
6970 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6692 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
6971 existing_var = | 6693 existing_var = |
6972 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 6694 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
6973 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6695 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
6974 | 6696 |
6975 // :await_jump_var = -1; | 6697 // :await_jump_var = -1; |
6976 LocalVariable* jump_var = | 6698 LocalVariable* jump_var = |
6977 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6699 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
6978 LiteralNode* init_value = new(Z) LiteralNode(TokenPosition::kNoSource, | 6700 LiteralNode* init_value = new (Z) |
6979 Smi::ZoneHandle(Smi::New(-1))); | 6701 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1))); |
6980 current_block_->statements->Add( | 6702 current_block_->statements->Add( |
6981 new(Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); | 6703 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); |
6982 | 6704 |
6983 // return new SyncIterable(body_closure); | 6705 // return new SyncIterable(body_closure); |
6984 const Class& iterable_class = | 6706 const Class& iterable_class = |
6985 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); | 6707 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); |
6986 ASSERT(!iterable_class.IsNull()); | 6708 ASSERT(!iterable_class.IsNull()); |
6987 const Function& iterable_constructor = Function::ZoneHandle(Z, | 6709 const Function& iterable_constructor = |
6988 iterable_class.LookupConstructorAllowPrivate( | 6710 Function::ZoneHandle(Z, iterable_class.LookupConstructorAllowPrivate( |
6989 Symbols::_SyncIterableConstructor())); | 6711 Symbols::_SyncIterableConstructor())); |
6990 ASSERT(!iterable_constructor.IsNull()); | 6712 ASSERT(!iterable_constructor.IsNull()); |
6991 | 6713 |
6992 const String& closure_name = String::Handle(Z, closure.name()); | 6714 const String& closure_name = String::Handle(Z, closure.name()); |
6993 ASSERT(closure_name.IsSymbol()); | 6715 ASSERT(closure_name.IsSymbol()); |
6994 | 6716 |
6995 ArgumentListNode* arguments = | 6717 ArgumentListNode* arguments = |
6996 new(Z) ArgumentListNode(TokenPosition::kNoSource); | 6718 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
6997 ClosureNode* closure_obj = new(Z) ClosureNode( | 6719 ClosureNode* closure_obj = new (Z) ClosureNode( |
6998 TokenPosition::kNoSource, closure, NULL, closure_body->scope()); | 6720 TokenPosition::kNoSource, closure, NULL, closure_body->scope()); |
6999 arguments->Add(closure_obj); | 6721 arguments->Add(closure_obj); |
7000 ConstructorCallNode* new_iterable = | 6722 ConstructorCallNode* new_iterable = new (Z) ConstructorCallNode( |
7001 new(Z) ConstructorCallNode(TokenPosition::kNoSource, | 6723 TokenPosition::kNoSource, TypeArguments::ZoneHandle(Z), |
7002 TypeArguments::ZoneHandle(Z), | 6724 iterable_constructor, arguments); |
7003 iterable_constructor, | |
7004 arguments); | |
7005 ReturnNode* return_node = | 6725 ReturnNode* return_node = |
7006 new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable); | 6726 new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable); |
7007 current_block_->statements->Add(return_node); | 6727 current_block_->statements->Add(return_node); |
7008 return CloseBlock(); | 6728 return CloseBlock(); |
7009 } | 6729 } |
7010 | 6730 |
7011 | 6731 |
7012 void Parser::AddAsyncClosureParameters(ParamList* params) { | 6732 void Parser::AddAsyncClosureParameters(ParamList* params) { |
7013 // Async closures have three optional parameters: | 6733 // Async closures have three optional parameters: |
7014 // * A continuation result. | 6734 // * A continuation result. |
7015 // * A continuation error. | 6735 // * A continuation error. |
7016 // * A continuation stack trace. | 6736 // * A continuation stack trace. |
7017 ASSERT(params->parameters->length() <= 1); | 6737 ASSERT(params->parameters->length() <= 1); |
7018 // Add implicit closure parameter if not yet present. | 6738 // Add implicit closure parameter if not yet present. |
7019 if (params->parameters->length() == 0) { | 6739 if (params->parameters->length() == 0) { |
7020 params->AddFinalParameter( | 6740 params->AddFinalParameter(TokenPosition::kMinSource, |
7021 TokenPosition::kMinSource, | 6741 &Symbols::ClosureParameter(), |
7022 &Symbols::ClosureParameter(), | 6742 &Object::dynamic_type()); |
7023 &Object::dynamic_type()); | |
7024 } | 6743 } |
7025 ParamDesc result_param; | 6744 ParamDesc result_param; |
7026 result_param.name = &Symbols::AsyncOperationParam(); | 6745 result_param.name = &Symbols::AsyncOperationParam(); |
7027 result_param.default_value = &Object::null_instance(); | 6746 result_param.default_value = &Object::null_instance(); |
7028 result_param.type = &Object::dynamic_type(); | 6747 result_param.type = &Object::dynamic_type(); |
7029 params->parameters->Add(result_param); | 6748 params->parameters->Add(result_param); |
7030 ParamDesc error_param; | 6749 ParamDesc error_param; |
7031 error_param.name = &Symbols::AsyncOperationErrorParam(); | 6750 error_param.name = &Symbols::AsyncOperationErrorParam(); |
7032 error_param.default_value = &Object::null_instance(); | 6751 error_param.default_value = &Object::null_instance(); |
7033 error_param.type = &Object::dynamic_type(); | 6752 error_param.type = &Object::dynamic_type(); |
(...skipping 20 matching lines...) Expand all Loading... |
7054 // compilation of this function. | 6773 // compilation of this function. |
7055 const Function& found_func = Function::Handle( | 6774 const Function& found_func = Function::Handle( |
7056 Z, I->LookupClosureFunction(innermost_function(), async_func_pos)); | 6775 Z, I->LookupClosureFunction(innermost_function(), async_func_pos)); |
7057 if (!found_func.IsNull()) { | 6776 if (!found_func.IsNull()) { |
7058 ASSERT(found_func.IsAsyncClosure()); | 6777 ASSERT(found_func.IsAsyncClosure()); |
7059 closure = found_func.raw(); | 6778 closure = found_func.raw(); |
7060 } else { | 6779 } else { |
7061 // Create the closure containing the body of this async function. | 6780 // Create the closure containing the body of this async function. |
7062 const String& async_func_name = | 6781 const String& async_func_name = |
7063 String::Handle(Z, innermost_function().name()); | 6782 String::Handle(Z, innermost_function().name()); |
7064 String& closure_name = String::Handle(Z, Symbols::NewFormatted(T, | 6783 String& closure_name = |
7065 "<%s_async_body>", async_func_name.ToCString())); | 6784 String::Handle(Z, Symbols::NewFormatted(T, "<%s_async_body>", |
7066 closure = Function::NewClosureFunction( | 6785 async_func_name.ToCString())); |
7067 closure_name, | 6786 closure = Function::NewClosureFunction(closure_name, innermost_function(), |
7068 innermost_function(), | 6787 async_func_pos); |
7069 async_func_pos); | |
7070 closure.set_is_generated_body(true); | 6788 closure.set_is_generated_body(true); |
7071 closure.set_result_type(Object::dynamic_type()); | 6789 closure.set_result_type(Object::dynamic_type()); |
7072 is_new_closure = true; | 6790 is_new_closure = true; |
7073 } | 6791 } |
7074 // Create the parameter list for the async body closure. | 6792 // Create the parameter list for the async body closure. |
7075 ParamList closure_params; | 6793 ParamList closure_params; |
7076 AddAsyncClosureParameters(&closure_params); | 6794 AddAsyncClosureParameters(&closure_params); |
7077 if (is_new_closure) { | 6795 if (is_new_closure) { |
7078 // Add the parameters to the newly created closure. | 6796 // Add the parameters to the newly created closure. |
7079 AddFormalParamsToFunction(&closure_params, closure); | 6797 AddFormalParamsToFunction(&closure_params, closure); |
(...skipping 17 matching lines...) Expand all Loading... |
7097 CaptureInstantiator(); | 6815 CaptureInstantiator(); |
7098 } | 6816 } |
7099 return closure.raw(); | 6817 return closure.raw(); |
7100 } | 6818 } |
7101 | 6819 |
7102 | 6820 |
7103 void Parser::AddContinuationVariables() { | 6821 void Parser::AddContinuationVariables() { |
7104 // Add to current block's scope: | 6822 // Add to current block's scope: |
7105 // var :await_jump_var; | 6823 // var :await_jump_var; |
7106 // var :await_ctx_var; | 6824 // var :await_ctx_var; |
7107 LocalVariable* await_jump_var = new (Z) LocalVariable( | 6825 LocalVariable* await_jump_var = |
7108 TokenPosition::kNoSource, | 6826 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7109 TokenPosition::kNoSource, | 6827 Symbols::AwaitJumpVar(), Object::dynamic_type()); |
7110 Symbols::AwaitJumpVar(), | |
7111 Object::dynamic_type()); | |
7112 current_block_->scope->AddVariable(await_jump_var); | 6828 current_block_->scope->AddVariable(await_jump_var); |
7113 LocalVariable* await_ctx_var = new (Z) LocalVariable( | 6829 LocalVariable* await_ctx_var = |
7114 TokenPosition::kNoSource, | 6830 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7115 TokenPosition::kNoSource, | 6831 Symbols::AwaitContextVar(), Object::dynamic_type()); |
7116 Symbols::AwaitContextVar(), | |
7117 Object::dynamic_type()); | |
7118 current_block_->scope->AddVariable(await_ctx_var); | 6832 current_block_->scope->AddVariable(await_ctx_var); |
7119 } | 6833 } |
7120 | 6834 |
7121 | 6835 |
7122 void Parser::AddAsyncClosureVariables() { | 6836 void Parser::AddAsyncClosureVariables() { |
7123 // Add to current block's scope: | 6837 // Add to current block's scope: |
7124 // var :async_op; | 6838 // var :async_op; |
7125 // var :async_then_callback; | 6839 // var :async_then_callback; |
7126 // var :async_catch_error_callback; | 6840 // var :async_catch_error_callback; |
7127 // var :async_completer; | 6841 // var :async_completer; |
7128 LocalVariable* async_op_var = new(Z) LocalVariable( | 6842 LocalVariable* async_op_var = |
7129 TokenPosition::kNoSource, | 6843 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7130 TokenPosition::kNoSource, | 6844 Symbols::AsyncOperation(), Object::dynamic_type()); |
7131 Symbols::AsyncOperation(), | |
7132 Object::dynamic_type()); | |
7133 current_block_->scope->AddVariable(async_op_var); | 6845 current_block_->scope->AddVariable(async_op_var); |
7134 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6846 LocalVariable* async_then_callback_var = new (Z) |
7135 TokenPosition::kNoSource, | 6847 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7136 TokenPosition::kNoSource, | 6848 Symbols::AsyncThenCallback(), Object::dynamic_type()); |
7137 Symbols::AsyncThenCallback(), | |
7138 Object::dynamic_type()); | |
7139 current_block_->scope->AddVariable(async_then_callback_var); | 6849 current_block_->scope->AddVariable(async_then_callback_var); |
7140 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6850 LocalVariable* async_catch_error_callback_var = new (Z) |
7141 TokenPosition::kNoSource, | 6851 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7142 TokenPosition::kNoSource, | 6852 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); |
7143 Symbols::AsyncCatchErrorCallback(), | |
7144 Object::dynamic_type()); | |
7145 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6853 current_block_->scope->AddVariable(async_catch_error_callback_var); |
7146 LocalVariable* async_completer = new(Z) LocalVariable( | 6854 LocalVariable* async_completer = |
7147 TokenPosition::kNoSource, | 6855 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7148 TokenPosition::kNoSource, | 6856 Symbols::AsyncCompleter(), Object::dynamic_type()); |
7149 Symbols::AsyncCompleter(), | |
7150 Object::dynamic_type()); | |
7151 current_block_->scope->AddVariable(async_completer); | 6857 current_block_->scope->AddVariable(async_completer); |
7152 } | 6858 } |
7153 | 6859 |
7154 | 6860 |
7155 void Parser::AddAsyncGeneratorVariables() { | 6861 void Parser::AddAsyncGeneratorVariables() { |
7156 // Add to current block's scope: | 6862 // Add to current block's scope: |
7157 // var :controller; | 6863 // var :controller; |
7158 // The :controller variable is used by the async generator closure to | 6864 // The :controller variable is used by the async generator closure to |
7159 // store the StreamController object to which the yielded expressions | 6865 // store the StreamController object to which the yielded expressions |
7160 // are added. | 6866 // are added. |
7161 // var :async_op; | 6867 // var :async_op; |
7162 // var :async_then_callback; | 6868 // var :async_then_callback; |
7163 // var :async_catch_error_callback; | 6869 // var :async_catch_error_callback; |
7164 // These variables are used to store the async generator closure containing | 6870 // These variables are used to store the async generator closure containing |
7165 // the body of the async* function. They are used by the await operator. | 6871 // the body of the async* function. They are used by the await operator. |
7166 LocalVariable* controller_var = new(Z) LocalVariable( | 6872 LocalVariable* controller_var = |
7167 TokenPosition::kNoSource, | 6873 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7168 TokenPosition::kNoSource, | 6874 Symbols::Controller(), Object::dynamic_type()); |
7169 Symbols::Controller(), | |
7170 Object::dynamic_type()); | |
7171 current_block_->scope->AddVariable(controller_var); | 6875 current_block_->scope->AddVariable(controller_var); |
7172 LocalVariable* async_op_var = new(Z) LocalVariable( | 6876 LocalVariable* async_op_var = |
7173 TokenPosition::kNoSource, | 6877 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7174 TokenPosition::kNoSource, | 6878 Symbols::AsyncOperation(), Object::dynamic_type()); |
7175 Symbols::AsyncOperation(), | |
7176 Object::dynamic_type()); | |
7177 current_block_->scope->AddVariable(async_op_var); | 6879 current_block_->scope->AddVariable(async_op_var); |
7178 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6880 LocalVariable* async_then_callback_var = new (Z) |
7179 TokenPosition::kNoSource, | 6881 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7180 TokenPosition::kNoSource, | 6882 Symbols::AsyncThenCallback(), Object::dynamic_type()); |
7181 Symbols::AsyncThenCallback(), | |
7182 Object::dynamic_type()); | |
7183 current_block_->scope->AddVariable(async_then_callback_var); | 6883 current_block_->scope->AddVariable(async_then_callback_var); |
7184 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6884 LocalVariable* async_catch_error_callback_var = new (Z) |
7185 TokenPosition::kNoSource, | 6885 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7186 TokenPosition::kNoSource, | 6886 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); |
7187 Symbols::AsyncCatchErrorCallback(), | |
7188 Object::dynamic_type()); | |
7189 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6887 current_block_->scope->AddVariable(async_catch_error_callback_var); |
7190 } | 6888 } |
7191 | 6889 |
7192 | 6890 |
7193 RawFunction* Parser::OpenAsyncGeneratorFunction( | 6891 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { |
7194 TokenPosition async_func_pos) { | |
7195 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 6892 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
7196 AddContinuationVariables(); | 6893 AddContinuationVariables(); |
7197 AddAsyncGeneratorVariables(); | 6894 AddAsyncGeneratorVariables(); |
7198 | 6895 |
7199 Function& closure = Function::Handle(Z); | 6896 Function& closure = Function::Handle(Z); |
7200 bool is_new_closure = false; | 6897 bool is_new_closure = false; |
7201 | 6898 |
7202 // Check whether a function for the asynchronous function body of | 6899 // Check whether a function for the asynchronous function body of |
7203 // this async generator has already been created by a previous | 6900 // this async generator has already been created by a previous |
7204 // compilation of this function. | 6901 // compilation of this function. |
7205 const Function& found_func = Function::Handle( | 6902 const Function& found_func = Function::Handle( |
7206 Z, I->LookupClosureFunction(innermost_function(), async_func_pos)); | 6903 Z, I->LookupClosureFunction(innermost_function(), async_func_pos)); |
7207 if (!found_func.IsNull()) { | 6904 if (!found_func.IsNull()) { |
7208 ASSERT(found_func.IsAsyncGenClosure()); | 6905 ASSERT(found_func.IsAsyncGenClosure()); |
7209 closure = found_func.raw(); | 6906 closure = found_func.raw(); |
7210 } else { | 6907 } else { |
7211 // Create the closure containing the body of this async generator function. | 6908 // Create the closure containing the body of this async generator function. |
7212 const String& async_generator_name = | 6909 const String& async_generator_name = |
7213 String::Handle(Z, innermost_function().name()); | 6910 String::Handle(Z, innermost_function().name()); |
7214 const String& closure_name = String::Handle(Z, Symbols::NewFormatted(T, | 6911 const String& closure_name = String::Handle( |
7215 "<%s_async_gen_body>", async_generator_name.ToCString())); | 6912 Z, Symbols::NewFormatted(T, "<%s_async_gen_body>", |
7216 closure = Function::NewClosureFunction(closure_name, | 6913 async_generator_name.ToCString())); |
7217 innermost_function(), | 6914 closure = Function::NewClosureFunction(closure_name, innermost_function(), |
7218 async_func_pos); | 6915 async_func_pos); |
7219 closure.set_is_generated_body(true); | 6916 closure.set_is_generated_body(true); |
7220 closure.set_result_type(Object::dynamic_type()); | 6917 closure.set_result_type(Object::dynamic_type()); |
7221 is_new_closure = true; | 6918 is_new_closure = true; |
7222 } | 6919 } |
7223 | 6920 |
7224 ParamList closure_params; | 6921 ParamList closure_params; |
7225 AddAsyncGenClosureParameters(&closure_params); | 6922 AddAsyncGenClosureParameters(&closure_params); |
7226 | 6923 |
7227 if (is_new_closure) { | 6924 if (is_new_closure) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7260 // return :controller.stream; | 6957 // return :controller.stream; |
7261 // } | 6958 // } |
7262 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, | 6959 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, |
7263 SequenceNode* closure_body) { | 6960 SequenceNode* closure_body) { |
7264 TRACE_PARSER("CloseAsyncGeneratorFunction"); | 6961 TRACE_PARSER("CloseAsyncGeneratorFunction"); |
7265 ASSERT(!closure_func.IsNull()); | 6962 ASSERT(!closure_func.IsNull()); |
7266 ASSERT(closure_body != NULL); | 6963 ASSERT(closure_body != NULL); |
7267 | 6964 |
7268 // Explicitly reference variables of the async genenerator function from the | 6965 // Explicitly reference variables of the async genenerator function from the |
7269 // closure body in order to mark them as captured. | 6966 // closure body in order to mark them as captured. |
7270 LocalVariable* existing_var = closure_body->scope()->LookupVariable( | 6967 LocalVariable* existing_var = |
7271 Symbols::AwaitJumpVar(), false); | 6968 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
7272 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6969 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7273 existing_var = closure_body->scope()->LookupVariable( | 6970 existing_var = |
7274 Symbols::AwaitContextVar(), false); | 6971 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
7275 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6972 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7276 existing_var = closure_body->scope()->LookupVariable( | 6973 existing_var = |
7277 Symbols::Controller(), false); | 6974 closure_body->scope()->LookupVariable(Symbols::Controller(), false); |
7278 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6975 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7279 existing_var = closure_body->scope()->LookupVariable( | 6976 existing_var = |
7280 Symbols::AsyncOperation(), false); | 6977 closure_body->scope()->LookupVariable(Symbols::AsyncOperation(), false); |
7281 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6978 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7282 existing_var = closure_body->scope()->LookupVariable( | 6979 existing_var = closure_body->scope()->LookupVariable( |
7283 Symbols::AsyncThenCallback(), false); | 6980 Symbols::AsyncThenCallback(), false); |
7284 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6981 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7285 existing_var = closure_body->scope()->LookupVariable( | 6982 existing_var = closure_body->scope()->LookupVariable( |
7286 Symbols::AsyncCatchErrorCallback(), false); | 6983 Symbols::AsyncCatchErrorCallback(), false); |
7287 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6984 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7288 | 6985 |
7289 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | 6986 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); |
7290 | 6987 |
7291 const Class& controller_class = Class::Handle(Z, | 6988 const Class& controller_class = Class::Handle( |
7292 async_lib.LookupClassAllowPrivate( | 6989 Z, |
7293 Symbols::_AsyncStarStreamController())); | 6990 async_lib.LookupClassAllowPrivate(Symbols::_AsyncStarStreamController())); |
7294 ASSERT(!controller_class.IsNull()); | 6991 ASSERT(!controller_class.IsNull()); |
7295 const Function& controller_constructor = Function::ZoneHandle(Z, | 6992 const Function& controller_constructor = Function::ZoneHandle( |
7296 controller_class.LookupConstructorAllowPrivate( | 6993 Z, controller_class.LookupConstructorAllowPrivate( |
7297 Symbols::_AsyncStarStreamControllerConstructor())); | 6994 Symbols::_AsyncStarStreamControllerConstructor())); |
7298 | 6995 |
7299 // :await_jump_var = -1; | 6996 // :await_jump_var = -1; |
7300 LocalVariable* jump_var = | 6997 LocalVariable* jump_var = |
7301 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6998 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
7302 LiteralNode* init_value = new(Z) LiteralNode(TokenPosition::kNoSource, | 6999 LiteralNode* init_value = new (Z) |
7303 Smi::ZoneHandle(Smi::New(-1))); | 7000 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1))); |
7304 current_block_->statements->Add( | 7001 current_block_->statements->Add( |
7305 new(Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); | 7002 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); |
7306 | 7003 |
7307 // Add to AST: | 7004 // Add to AST: |
7308 // :async_op = <closure>; (containing the original body) | 7005 // :async_op = <closure>; (containing the original body) |
7309 LocalVariable* async_op_var = | 7006 LocalVariable* async_op_var = |
7310 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); | 7007 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
7311 ClosureNode* closure_obj = new(Z) ClosureNode( | 7008 ClosureNode* closure_obj = new (Z) ClosureNode( |
7312 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); | 7009 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); |
7313 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 7010 StoreLocalNode* store_async_op = new (Z) |
7314 TokenPosition::kNoSource, | 7011 StoreLocalNode(TokenPosition::kNoSource, async_op_var, closure_obj); |
7315 async_op_var, | |
7316 closure_obj); | |
7317 | 7012 |
7318 current_block_->statements->Add(store_async_op); | 7013 current_block_->statements->Add(store_async_op); |
7319 | 7014 |
7320 // :async_then_callback = _asyncThenWrapperHelper(:async_op) | 7015 // :async_then_callback = _asyncThenWrapperHelper(:async_op) |
7321 const Function& async_then_wrapper_helper = Function::ZoneHandle( | 7016 const Function& async_then_wrapper_helper = Function::ZoneHandle( |
7322 Z, async_lib.LookupFunctionAllowPrivate( | 7017 Z, |
7323 Symbols::AsyncThenWrapperHelper())); | 7018 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncThenWrapperHelper())); |
7324 ASSERT(!async_then_wrapper_helper.IsNull()); | 7019 ASSERT(!async_then_wrapper_helper.IsNull()); |
7325 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( | 7020 ArgumentListNode* async_then_wrapper_helper_args = |
7326 TokenPosition::kNoSource); | 7021 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
7327 async_then_wrapper_helper_args->Add( | 7022 async_then_wrapper_helper_args->Add( |
7328 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); | 7023 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); |
7329 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( | 7024 StaticCallNode* then_wrapper_call = new (Z) |
7330 TokenPosition::kNoSource, | 7025 StaticCallNode(TokenPosition::kNoSource, async_then_wrapper_helper, |
7331 async_then_wrapper_helper, | 7026 async_then_wrapper_helper_args); |
7332 async_then_wrapper_helper_args); | |
7333 LocalVariable* async_then_callback_var = | 7027 LocalVariable* async_then_callback_var = |
7334 current_block_->scope->LookupVariable( | 7028 current_block_->scope->LookupVariable(Symbols::AsyncThenCallback(), |
7335 Symbols::AsyncThenCallback(), false); | 7029 false); |
7336 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( | 7030 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( |
7337 TokenPosition::kNoSource, | 7031 TokenPosition::kNoSource, async_then_callback_var, then_wrapper_call); |
7338 async_then_callback_var, | |
7339 then_wrapper_call); | |
7340 | 7032 |
7341 current_block_->statements->Add(store_async_then_callback); | 7033 current_block_->statements->Add(store_async_then_callback); |
7342 | 7034 |
7343 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) | 7035 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) |
7344 | 7036 |
7345 const Function& async_error_wrapper_helper = Function::ZoneHandle( | 7037 const Function& async_error_wrapper_helper = Function::ZoneHandle( |
7346 Z, async_lib.LookupFunctionAllowPrivate( | 7038 Z, |
7347 Symbols::AsyncErrorWrapperHelper())); | 7039 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncErrorWrapperHelper())); |
7348 ASSERT(!async_error_wrapper_helper.IsNull()); | 7040 ASSERT(!async_error_wrapper_helper.IsNull()); |
7349 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( | 7041 ArgumentListNode* async_error_wrapper_helper_args = |
7350 TokenPosition::kNoSource); | 7042 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
7351 async_error_wrapper_helper_args->Add( | 7043 async_error_wrapper_helper_args->Add( |
7352 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); | 7044 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); |
7353 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( | 7045 StaticCallNode* error_wrapper_call = new (Z) |
7354 TokenPosition::kNoSource, | 7046 StaticCallNode(TokenPosition::kNoSource, async_error_wrapper_helper, |
7355 async_error_wrapper_helper, | 7047 async_error_wrapper_helper_args); |
7356 async_error_wrapper_helper_args); | |
7357 LocalVariable* async_catch_error_callback_var = | 7048 LocalVariable* async_catch_error_callback_var = |
7358 current_block_->scope->LookupVariable( | 7049 current_block_->scope->LookupVariable(Symbols::AsyncCatchErrorCallback(), |
7359 Symbols::AsyncCatchErrorCallback(), false); | 7050 false); |
7360 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( | 7051 StoreLocalNode* store_async_catch_error_callback = new (Z) |
7361 TokenPosition::kNoSource, | 7052 StoreLocalNode(TokenPosition::kNoSource, async_catch_error_callback_var, |
7362 async_catch_error_callback_var, | 7053 error_wrapper_call); |
7363 error_wrapper_call); | |
7364 | 7054 |
7365 current_block_->statements->Add(store_async_catch_error_callback); | 7055 current_block_->statements->Add(store_async_catch_error_callback); |
7366 | 7056 |
7367 // :controller = new _AsyncStarStreamController(body_closure); | 7057 // :controller = new _AsyncStarStreamController(body_closure); |
7368 ArgumentListNode* arguments = | 7058 ArgumentListNode* arguments = |
7369 new(Z) ArgumentListNode(TokenPosition::kNoSource); | 7059 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
7370 arguments->Add( | 7060 arguments->Add(new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); |
7371 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); | |
7372 ConstructorCallNode* controller_constructor_call = | 7061 ConstructorCallNode* controller_constructor_call = |
7373 new(Z) ConstructorCallNode(TokenPosition::kNoSource, | 7062 new (Z) ConstructorCallNode(TokenPosition::kNoSource, |
7374 TypeArguments::ZoneHandle(Z), | 7063 TypeArguments::ZoneHandle(Z), |
7375 controller_constructor, | 7064 controller_constructor, arguments); |
7376 arguments); | |
7377 LocalVariable* controller_var = | 7065 LocalVariable* controller_var = |
7378 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 7066 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
7379 StoreLocalNode* store_controller = | 7067 StoreLocalNode* store_controller = new (Z) StoreLocalNode( |
7380 new(Z) StoreLocalNode(TokenPosition::kNoSource, | 7068 TokenPosition::kNoSource, controller_var, controller_constructor_call); |
7381 controller_var, | |
7382 controller_constructor_call); | |
7383 current_block_->statements->Add(store_controller); | 7069 current_block_->statements->Add(store_controller); |
7384 | 7070 |
7385 // return :controller.stream; | 7071 // return :controller.stream; |
7386 ReturnNode* return_node = new(Z) ReturnNode(TokenPosition::kNoSource, | 7072 ReturnNode* return_node = new (Z) ReturnNode( |
7387 new(Z) InstanceGetterNode(TokenPosition::kNoSource, | 7073 TokenPosition::kNoSource, |
7388 new(Z) LoadLocalNode(TokenPosition::kNoSource, | 7074 new (Z) InstanceGetterNode( |
7389 controller_var), | 7075 TokenPosition::kNoSource, |
7390 Symbols::Stream())); | 7076 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var), |
| 7077 Symbols::Stream())); |
7391 current_block_->statements->Add(return_node); | 7078 current_block_->statements->Add(return_node); |
7392 return CloseBlock(); | 7079 return CloseBlock(); |
7393 } | 7080 } |
7394 | 7081 |
7395 | 7082 |
7396 void Parser::OpenAsyncGeneratorClosure() { | 7083 void Parser::OpenAsyncGeneratorClosure() { |
7397 async_temp_scope_ = current_block_->scope; | 7084 async_temp_scope_ = current_block_->scope; |
7398 OpenAsyncTryBlock(); | 7085 OpenAsyncTryBlock(); |
7399 } | 7086 } |
7400 | 7087 |
7401 | 7088 |
7402 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { | 7089 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { |
7403 // We need a temporary expression to store intermediate return values. | 7090 // We need a temporary expression to store intermediate return values. |
7404 parsed_function()->EnsureExpressionTemp(); | 7091 parsed_function()->EnsureExpressionTemp(); |
7405 | 7092 |
7406 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); | 7093 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); |
7407 ASSERT(new_body != NULL); | 7094 ASSERT(new_body != NULL); |
7408 ASSERT(new_body->scope() != NULL); | 7095 ASSERT(new_body->scope() != NULL); |
7409 return new_body; | 7096 return new_body; |
7410 } | 7097 } |
7411 | 7098 |
7412 | 7099 |
7413 // Add a return node to the sequence if necessary. | 7100 // Add a return node to the sequence if necessary. |
7414 void Parser::EnsureHasReturnStatement(SequenceNode* seq, | 7101 void Parser::EnsureHasReturnStatement(SequenceNode* seq, |
7415 TokenPosition return_pos) { | 7102 TokenPosition return_pos) { |
7416 if ((seq->length() == 0) || | 7103 if ((seq->length() == 0) || !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { |
7417 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { | |
7418 const Function& func = innermost_function(); | 7104 const Function& func = innermost_function(); |
7419 // The implicit return value of synchronous generator closures is false, | 7105 // The implicit return value of synchronous generator closures is false, |
7420 // to indicate that there are no more elements in the iterable. | 7106 // to indicate that there are no more elements in the iterable. |
7421 // In other cases the implicit return value is null. | 7107 // In other cases the implicit return value is null. |
7422 AstNode* return_value = func.IsSyncGenClosure() | 7108 AstNode* return_value = |
7423 ? new LiteralNode(return_pos, Bool::False()) | 7109 func.IsSyncGenClosure() |
7424 : new LiteralNode(return_pos, Instance::ZoneHandle()); | 7110 ? new LiteralNode(return_pos, Bool::False()) |
| 7111 : new LiteralNode(return_pos, Instance::ZoneHandle()); |
7425 seq->Add(new ReturnNode(return_pos, return_value)); | 7112 seq->Add(new ReturnNode(return_pos, return_value)); |
7426 } | 7113 } |
7427 } | 7114 } |
7428 | 7115 |
7429 | 7116 |
7430 SequenceNode* Parser::CloseBlock() { | 7117 SequenceNode* Parser::CloseBlock() { |
7431 SequenceNode* statements = current_block_->statements; | 7118 SequenceNode* statements = current_block_->statements; |
7432 if (current_block_->scope != NULL) { | 7119 if (current_block_->scope != NULL) { |
7433 // Record the begin and end token index of the scope. | 7120 // Record the begin and end token index of the scope. |
7434 ASSERT(statements != NULL); | 7121 ASSERT(statements != NULL); |
(...skipping 22 matching lines...) Expand all Loading... |
7457 existing_var = | 7144 existing_var = |
7458 closure_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false); | 7145 closure_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false); |
7459 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7146 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7460 | 7147 |
7461 // Create and return a new future that executes a closure with the current | 7148 // Create and return a new future that executes a closure with the current |
7462 // body. | 7149 // body. |
7463 | 7150 |
7464 // No need to capture parameters or other variables, since they have already | 7151 // No need to capture parameters or other variables, since they have already |
7465 // been captured in the corresponding scope as the body has been parsed within | 7152 // been captured in the corresponding scope as the body has been parsed within |
7466 // a nested block (contained in the async function's block). | 7153 // a nested block (contained in the async function's block). |
7467 const Class& future = | 7154 const Class& future = Class::ZoneHandle(Z, I->object_store()->future_class()); |
7468 Class::ZoneHandle(Z, I->object_store()->future_class()); | |
7469 ASSERT(!future.IsNull()); | 7155 ASSERT(!future.IsNull()); |
7470 const Function& constructor = Function::ZoneHandle(Z, | 7156 const Function& constructor = Function::ZoneHandle( |
7471 future.LookupFunction(Symbols::FutureMicrotask())); | 7157 Z, future.LookupFunction(Symbols::FutureMicrotask())); |
7472 ASSERT(!constructor.IsNull()); | 7158 ASSERT(!constructor.IsNull()); |
7473 const Class& completer = | 7159 const Class& completer = |
7474 Class::ZoneHandle(Z, I->object_store()->completer_class()); | 7160 Class::ZoneHandle(Z, I->object_store()->completer_class()); |
7475 ASSERT(!completer.IsNull()); | 7161 ASSERT(!completer.IsNull()); |
7476 const Function& completer_constructor = Function::ZoneHandle(Z, | 7162 const Function& completer_constructor = Function::ZoneHandle( |
7477 completer.LookupFunction(Symbols::CompleterSyncConstructor())); | 7163 Z, completer.LookupFunction(Symbols::CompleterSyncConstructor())); |
7478 ASSERT(!completer_constructor.IsNull()); | 7164 ASSERT(!completer_constructor.IsNull()); |
7479 | 7165 |
7480 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 7166 LocalVariable* async_completer = |
7481 Symbols::AsyncCompleter(), false); | 7167 current_block_->scope->LookupVariable(Symbols::AsyncCompleter(), false); |
7482 | 7168 |
7483 const TokenPosition token_pos = ST(closure_body->token_pos()); | 7169 const TokenPosition token_pos = ST(closure_body->token_pos()); |
7484 // Add to AST: | 7170 // Add to AST: |
7485 // :async_completer = new Completer.sync(); | 7171 // :async_completer = new Completer.sync(); |
7486 ArgumentListNode* empty_args = | 7172 ArgumentListNode* empty_args = new (Z) ArgumentListNode(token_pos); |
7487 new (Z) ArgumentListNode(token_pos); | 7173 ConstructorCallNode* completer_constructor_node = |
7488 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( | 7174 new (Z) ConstructorCallNode(token_pos, TypeArguments::ZoneHandle(Z), |
7489 token_pos, | 7175 completer_constructor, empty_args); |
7490 TypeArguments::ZoneHandle(Z), | 7176 StoreLocalNode* store_completer = new (Z) |
7491 completer_constructor, | 7177 StoreLocalNode(token_pos, async_completer, completer_constructor_node); |
7492 empty_args); | |
7493 StoreLocalNode* store_completer = new (Z) StoreLocalNode( | |
7494 token_pos, | |
7495 async_completer, | |
7496 completer_constructor_node); | |
7497 current_block_->statements->Add(store_completer); | 7178 current_block_->statements->Add(store_completer); |
7498 | 7179 |
7499 // :await_jump_var = -1; | 7180 // :await_jump_var = -1; |
7500 LocalVariable* jump_var = | 7181 LocalVariable* jump_var = |
7501 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 7182 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
7502 LiteralNode* init_value = | 7183 LiteralNode* init_value = |
7503 new(Z) LiteralNode(token_pos, | 7184 new (Z) LiteralNode(token_pos, Smi::ZoneHandle(Smi::New(-1))); |
7504 Smi::ZoneHandle(Smi::New(-1))); | |
7505 current_block_->statements->Add( | 7185 current_block_->statements->Add( |
7506 new(Z) StoreLocalNode(token_pos, jump_var, init_value)); | 7186 new (Z) StoreLocalNode(token_pos, jump_var, init_value)); |
7507 | 7187 |
7508 // Add to AST: | 7188 // Add to AST: |
7509 // :async_op = <closure>; (containing the original body) | 7189 // :async_op = <closure>; (containing the original body) |
7510 LocalVariable* async_op_var = current_block_->scope->LookupVariable( | 7190 LocalVariable* async_op_var = |
7511 Symbols::AsyncOperation(), false); | 7191 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
7512 ClosureNode* cn = new(Z) ClosureNode( | 7192 ClosureNode* cn = |
7513 token_pos, closure, NULL, closure_body->scope()); | 7193 new (Z) ClosureNode(token_pos, closure, NULL, closure_body->scope()); |
7514 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 7194 StoreLocalNode* store_async_op = |
7515 token_pos, | 7195 new (Z) StoreLocalNode(token_pos, async_op_var, cn); |
7516 async_op_var, | |
7517 cn); | |
7518 current_block_->statements->Add(store_async_op); | 7196 current_block_->statements->Add(store_async_op); |
7519 | 7197 |
7520 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | 7198 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); |
7521 // :async_then_callback = _asyncThenWrapperHelper(:async_op) | 7199 // :async_then_callback = _asyncThenWrapperHelper(:async_op) |
7522 const Function& async_then_wrapper_helper = Function::ZoneHandle( | 7200 const Function& async_then_wrapper_helper = Function::ZoneHandle( |
7523 Z, async_lib.LookupFunctionAllowPrivate( | 7201 Z, |
7524 Symbols::AsyncThenWrapperHelper())); | 7202 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncThenWrapperHelper())); |
7525 ASSERT(!async_then_wrapper_helper.IsNull()); | 7203 ASSERT(!async_then_wrapper_helper.IsNull()); |
7526 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( | 7204 ArgumentListNode* async_then_wrapper_helper_args = |
7527 token_pos); | 7205 new (Z) ArgumentListNode(token_pos); |
7528 async_then_wrapper_helper_args->Add( | 7206 async_then_wrapper_helper_args->Add( |
7529 new (Z) LoadLocalNode(token_pos, async_op_var)); | 7207 new (Z) LoadLocalNode(token_pos, async_op_var)); |
7530 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( | 7208 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( |
7531 token_pos, | 7209 token_pos, async_then_wrapper_helper, async_then_wrapper_helper_args); |
7532 async_then_wrapper_helper, | |
7533 async_then_wrapper_helper_args); | |
7534 LocalVariable* async_then_callback_var = | 7210 LocalVariable* async_then_callback_var = |
7535 current_block_->scope->LookupVariable( | 7211 current_block_->scope->LookupVariable(Symbols::AsyncThenCallback(), |
7536 Symbols::AsyncThenCallback(), false); | 7212 false); |
7537 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( | 7213 StoreLocalNode* store_async_then_callback = new (Z) |
7538 token_pos, | 7214 StoreLocalNode(token_pos, async_then_callback_var, then_wrapper_call); |
7539 async_then_callback_var, | |
7540 then_wrapper_call); | |
7541 | 7215 |
7542 current_block_->statements->Add(store_async_then_callback); | 7216 current_block_->statements->Add(store_async_then_callback); |
7543 | 7217 |
7544 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) | 7218 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) |
7545 | 7219 |
7546 const Function& async_error_wrapper_helper = Function::ZoneHandle( | 7220 const Function& async_error_wrapper_helper = Function::ZoneHandle( |
7547 Z, async_lib.LookupFunctionAllowPrivate( | 7221 Z, |
7548 Symbols::AsyncErrorWrapperHelper())); | 7222 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncErrorWrapperHelper())); |
7549 ASSERT(!async_error_wrapper_helper.IsNull()); | 7223 ASSERT(!async_error_wrapper_helper.IsNull()); |
7550 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( | 7224 ArgumentListNode* async_error_wrapper_helper_args = |
7551 token_pos); | 7225 new (Z) ArgumentListNode(token_pos); |
7552 async_error_wrapper_helper_args->Add( | 7226 async_error_wrapper_helper_args->Add( |
7553 new (Z) LoadLocalNode(token_pos, async_op_var)); | 7227 new (Z) LoadLocalNode(token_pos, async_op_var)); |
7554 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( | 7228 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( |
7555 token_pos, | 7229 token_pos, async_error_wrapper_helper, async_error_wrapper_helper_args); |
7556 async_error_wrapper_helper, | |
7557 async_error_wrapper_helper_args); | |
7558 LocalVariable* async_catch_error_callback_var = | 7230 LocalVariable* async_catch_error_callback_var = |
7559 current_block_->scope->LookupVariable( | 7231 current_block_->scope->LookupVariable(Symbols::AsyncCatchErrorCallback(), |
7560 Symbols::AsyncCatchErrorCallback(), false); | 7232 false); |
7561 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( | 7233 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( |
7562 token_pos, | 7234 token_pos, async_catch_error_callback_var, error_wrapper_call); |
7563 async_catch_error_callback_var, | |
7564 error_wrapper_call); | |
7565 | 7235 |
7566 current_block_->statements->Add(store_async_catch_error_callback); | 7236 current_block_->statements->Add(store_async_catch_error_callback); |
7567 | 7237 |
7568 // Add to AST: | 7238 // Add to AST: |
7569 // new Future.microtask(:async_op); | 7239 // new Future.microtask(:async_op); |
7570 ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos); | 7240 ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos); |
7571 arguments->Add(new (Z) LoadLocalNode( | 7241 arguments->Add(new (Z) LoadLocalNode(token_pos, async_op_var)); |
7572 token_pos, async_op_var)); | |
7573 ConstructorCallNode* future_node = new (Z) ConstructorCallNode( | 7242 ConstructorCallNode* future_node = new (Z) ConstructorCallNode( |
7574 token_pos, TypeArguments::ZoneHandle(Z), constructor, | 7243 token_pos, TypeArguments::ZoneHandle(Z), constructor, arguments); |
7575 arguments); | |
7576 current_block_->statements->Add(future_node); | 7244 current_block_->statements->Add(future_node); |
7577 | 7245 |
7578 // Add to AST: | 7246 // Add to AST: |
7579 // return :async_completer.future; | 7247 // return :async_completer.future; |
7580 ReturnNode* return_node = new (Z) ReturnNode( | 7248 ReturnNode* return_node = new (Z) ReturnNode( |
7581 token_pos, | 7249 token_pos, |
7582 new (Z) InstanceGetterNode( | 7250 new (Z) InstanceGetterNode( |
7583 token_pos, | 7251 token_pos, new (Z) LoadLocalNode(token_pos, async_completer), |
7584 new (Z) LoadLocalNode( | |
7585 token_pos, | |
7586 async_completer), | |
7587 Symbols::CompleterFuture())); | 7252 Symbols::CompleterFuture())); |
7588 current_block_->statements->Add(return_node); | 7253 current_block_->statements->Add(return_node); |
7589 return CloseBlock(); | 7254 return CloseBlock(); |
7590 } | 7255 } |
7591 | 7256 |
7592 | 7257 |
7593 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { | 7258 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { |
7594 // We need a temporary expression to store intermediate return values. | 7259 // We need a temporary expression to store intermediate return values. |
7595 parsed_function()->EnsureExpressionTemp(); | 7260 parsed_function()->EnsureExpressionTemp(); |
7596 | 7261 |
(...skipping 28 matching lines...) Expand all Loading... |
7625 // with the formal parameter types and names. | 7290 // with the formal parameter types and names. |
7626 void Parser::AddFormalParamsToFunction(const ParamList* params, | 7291 void Parser::AddFormalParamsToFunction(const ParamList* params, |
7627 const Function& func) { | 7292 const Function& func) { |
7628 ASSERT((params != NULL) && (params->parameters != NULL)); | 7293 ASSERT((params != NULL) && (params->parameters != NULL)); |
7629 ASSERT((params->num_optional_parameters > 0) == | 7294 ASSERT((params->num_optional_parameters > 0) == |
7630 (params->has_optional_positional_parameters || | 7295 (params->has_optional_positional_parameters || |
7631 params->has_optional_named_parameters)); | 7296 params->has_optional_named_parameters)); |
7632 if (!Utils::IsInt(16, params->num_fixed_parameters) || | 7297 if (!Utils::IsInt(16, params->num_fixed_parameters) || |
7633 !Utils::IsInt(16, params->num_optional_parameters)) { | 7298 !Utils::IsInt(16, params->num_optional_parameters)) { |
7634 const Script& script = Script::Handle(Class::Handle(func.Owner()).script()); | 7299 const Script& script = Script::Handle(Class::Handle(func.Owner()).script()); |
7635 Report::MessageF(Report::kError, | 7300 Report::MessageF(Report::kError, script, func.token_pos(), |
7636 script, func.token_pos(), Report::AtLocation, | 7301 Report::AtLocation, "too many formal parameters"); |
7637 "too many formal parameters"); | |
7638 } | 7302 } |
7639 func.set_num_fixed_parameters(params->num_fixed_parameters); | 7303 func.set_num_fixed_parameters(params->num_fixed_parameters); |
7640 func.SetNumOptionalParameters(params->num_optional_parameters, | 7304 func.SetNumOptionalParameters(params->num_optional_parameters, |
7641 params->has_optional_positional_parameters); | 7305 params->has_optional_positional_parameters); |
7642 const int num_parameters = params->parameters->length(); | 7306 const int num_parameters = params->parameters->length(); |
7643 ASSERT(num_parameters == func.NumParameters()); | 7307 ASSERT(num_parameters == func.NumParameters()); |
7644 ASSERT(func.parameter_types() == Object::empty_array().raw()); | 7308 ASSERT(func.parameter_types() == Object::empty_array().raw()); |
7645 ASSERT(func.parameter_names() == Object::empty_array().raw()); | 7309 ASSERT(func.parameter_names() == Object::empty_array().raw()); |
7646 func.set_parameter_types(Array::Handle(Array::New(num_parameters, | 7310 func.set_parameter_types( |
7647 Heap::kOld))); | 7311 Array::Handle(Array::New(num_parameters, Heap::kOld))); |
7648 func.set_parameter_names(Array::Handle(Array::New(num_parameters, | 7312 func.set_parameter_names( |
7649 Heap::kOld))); | 7313 Array::Handle(Array::New(num_parameters, Heap::kOld))); |
7650 for (int i = 0; i < num_parameters; i++) { | 7314 for (int i = 0; i < num_parameters; i++) { |
7651 ParamDesc& param_desc = (*params->parameters)[i]; | 7315 ParamDesc& param_desc = (*params->parameters)[i]; |
7652 func.SetParameterTypeAt(i, *param_desc.type); | 7316 func.SetParameterTypeAt(i, *param_desc.type); |
7653 func.SetParameterNameAt(i, *param_desc.name); | 7317 func.SetParameterNameAt(i, *param_desc.name); |
7654 if (param_desc.is_field_initializer && !func.IsGenerativeConstructor()) { | 7318 if (param_desc.is_field_initializer && !func.IsGenerativeConstructor()) { |
7655 // Redirecting constructors are detected later in ParseConstructor. | 7319 // Redirecting constructors are detected later in ParseConstructor. |
7656 ReportError(param_desc.name_pos, | 7320 ReportError(param_desc.name_pos, |
7657 "only generative constructors may have " | 7321 "only generative constructors may have " |
7658 "initializing formal parameters"); | 7322 "initializing formal parameters"); |
7659 } | 7323 } |
7660 } | 7324 } |
7661 } | 7325 } |
7662 | 7326 |
7663 | 7327 |
7664 // Populate local scope with the formal parameters. | 7328 // Populate local scope with the formal parameters. |
7665 void Parser::AddFormalParamsToScope(const ParamList* params, | 7329 void Parser::AddFormalParamsToScope(const ParamList* params, |
7666 LocalScope* scope) { | 7330 LocalScope* scope) { |
7667 ASSERT((params != NULL) && (params->parameters != NULL)); | 7331 ASSERT((params != NULL) && (params->parameters != NULL)); |
7668 ASSERT(scope != NULL); | 7332 ASSERT(scope != NULL); |
7669 const int num_parameters = params->parameters->length(); | 7333 const int num_parameters = params->parameters->length(); |
7670 for (int i = 0; i < num_parameters; i++) { | 7334 for (int i = 0; i < num_parameters; i++) { |
7671 ParamDesc& param_desc = (*params->parameters)[i]; | 7335 ParamDesc& param_desc = (*params->parameters)[i]; |
7672 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); | 7336 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); |
7673 const String* name = param_desc.name; | 7337 const String* name = param_desc.name; |
7674 LocalVariable* parameter = new(Z) LocalVariable( | 7338 LocalVariable* parameter = new (Z) LocalVariable( |
7675 param_desc.name_pos, | 7339 param_desc.name_pos, param_desc.name_pos, *name, *param_desc.type); |
7676 param_desc.name_pos, | |
7677 *name, | |
7678 *param_desc.type); | |
7679 if (!scope->InsertParameterAt(i, parameter)) { | 7340 if (!scope->InsertParameterAt(i, parameter)) { |
7680 ReportError(param_desc.name_pos, | 7341 ReportError(param_desc.name_pos, "name '%s' already exists in scope", |
7681 "name '%s' already exists in scope", | |
7682 param_desc.name->ToCString()); | 7342 param_desc.name->ToCString()); |
7683 } | 7343 } |
7684 param_desc.var = parameter; | 7344 param_desc.var = parameter; |
7685 if (param_desc.is_final) { | 7345 if (param_desc.is_final) { |
7686 parameter->set_is_final(); | 7346 parameter->set_is_final(); |
7687 } | 7347 } |
7688 if (FLAG_initializing_formal_access) { | 7348 if (FLAG_initializing_formal_access) { |
7689 // Field initializer parameters are implicitly final. | 7349 // Field initializer parameters are implicitly final. |
7690 ASSERT(!param_desc.is_field_initializer || param_desc.is_final); | 7350 ASSERT(!param_desc.is_field_initializer || param_desc.is_final); |
7691 } else if (param_desc.is_field_initializer) { | 7351 } else if (param_desc.is_field_initializer) { |
7692 parameter->set_invisible(true); | 7352 parameter->set_invisible(true); |
7693 } | 7353 } |
7694 } | 7354 } |
7695 } | 7355 } |
7696 | 7356 |
7697 | 7357 |
7698 // Builds ReturnNode/NativeBodyNode for a native function. | 7358 // Builds ReturnNode/NativeBodyNode for a native function. |
7699 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 7359 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
7700 const Function& func) { | 7360 const Function& func) { |
7701 ASSERT(func.is_native()); | 7361 ASSERT(func.is_native()); |
7702 ASSERT(func.NumParameters() == params->parameters->length()); | 7362 ASSERT(func.NumParameters() == params->parameters->length()); |
7703 TRACE_PARSER("ParseNativeFunctionBlock"); | 7363 TRACE_PARSER("ParseNativeFunctionBlock"); |
7704 | 7364 |
7705 // Parse the function name out. | 7365 // Parse the function name out. |
7706 const String& native_name = ParseNativeDeclaration(); | 7366 const String& native_name = ParseNativeDeclaration(); |
7707 | 7367 |
7708 // Now add the NativeBodyNode and return statement. | 7368 // Now add the NativeBodyNode and return statement. |
7709 current_block_->statements->Add(new(Z) ReturnNode( | 7369 current_block_->statements->Add(new (Z) ReturnNode( |
7710 TokenPos(), | 7370 TokenPos(), |
7711 new(Z) NativeBodyNode( | 7371 new (Z) NativeBodyNode(TokenPos(), Function::ZoneHandle(Z, func.raw()), |
7712 TokenPos(), | 7372 native_name, current_block_->scope, |
7713 Function::ZoneHandle(Z, func.raw()), | 7373 FLAG_link_natives_lazily))); |
7714 native_name, | |
7715 current_block_->scope, | |
7716 FLAG_link_natives_lazily))); | |
7717 } | 7374 } |
7718 | 7375 |
7719 | 7376 |
7720 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 7377 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
7721 ASSERT(!current_function().is_static()); | 7378 ASSERT(!current_function().is_static()); |
7722 return from_scope->LookupVariable(Symbols::This(), test_only); | 7379 return from_scope->LookupVariable(Symbols::This(), test_only); |
7723 } | 7380 } |
7724 | 7381 |
7725 | 7382 |
7726 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, | 7383 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, |
7727 bool test_only) { | 7384 bool test_only) { |
7728 ASSERT(current_function().IsInFactoryScope()); | 7385 ASSERT(current_function().IsInFactoryScope()); |
7729 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), | 7386 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), |
7730 test_only); | 7387 test_only); |
7731 } | 7388 } |
7732 | 7389 |
7733 | 7390 |
7734 void Parser::CaptureInstantiator() { | 7391 void Parser::CaptureInstantiator() { |
7735 ASSERT(FunctionLevel() > 0); | 7392 ASSERT(FunctionLevel() > 0); |
7736 const String* variable_name = current_function().IsInFactoryScope() ? | 7393 const String* variable_name = current_function().IsInFactoryScope() |
7737 &Symbols::TypeArgumentsParameter() : &Symbols::This(); | 7394 ? &Symbols::TypeArgumentsParameter() |
| 7395 : &Symbols::This(); |
7738 current_block_->scope->CaptureVariable( | 7396 current_block_->scope->CaptureVariable( |
7739 current_block_->scope->LookupVariable(*variable_name, true)); | 7397 current_block_->scope->LookupVariable(*variable_name, true)); |
7740 } | 7398 } |
7741 | 7399 |
7742 | 7400 |
7743 void Parser::CaptureFunctionInstantiator() { | 7401 void Parser::CaptureFunctionInstantiator() { |
7744 ASSERT(FunctionLevel() > 0); | 7402 ASSERT(FunctionLevel() > 0); |
7745 const String* variable_name = &Symbols::FunctionInstantiatorVar(); | 7403 const String* variable_name = &Symbols::FunctionInstantiatorVar(); |
7746 current_block_->scope->CaptureVariable( | 7404 current_block_->scope->CaptureVariable( |
7747 current_block_->scope->LookupVariable(*variable_name, true)); | 7405 current_block_->scope->LookupVariable(*variable_name, true)); |
7748 } | 7406 } |
7749 | 7407 |
7750 | 7408 |
7751 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { | 7409 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { |
7752 // A nested function may access 'this', referring to the receiver of the | 7410 // A nested function may access 'this', referring to the receiver of the |
7753 // outermost enclosing function. | 7411 // outermost enclosing function. |
7754 const bool kTestOnly = false; | 7412 const bool kTestOnly = false; |
7755 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7413 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
7756 if (receiver == NULL) { | 7414 if (receiver == NULL) { |
7757 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7415 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
7758 } | 7416 } |
7759 return new(Z) LoadLocalNode(TokenPos(), receiver); | 7417 return new (Z) LoadLocalNode(TokenPos(), receiver); |
7760 } | 7418 } |
7761 | 7419 |
7762 | 7420 |
7763 InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos, | 7421 InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos, |
7764 AstNode* object, | 7422 AstNode* object, |
7765 const String& name) { | 7423 const String& name) { |
7766 return new(Z) InstanceGetterNode(token_pos, object, name); | 7424 return new (Z) InstanceGetterNode(token_pos, object, name); |
7767 } | 7425 } |
7768 | 7426 |
7769 | 7427 |
7770 // Returns ast nodes of the variable initialization. | 7428 // Returns ast nodes of the variable initialization. |
7771 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 7429 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
7772 bool is_final, | 7430 bool is_final, |
7773 bool is_const, | 7431 bool is_const, |
7774 SequenceNode** await_preamble) { | 7432 SequenceNode** await_preamble) { |
7775 TRACE_PARSER("ParseVariableDeclaration"); | 7433 TRACE_PARSER("ParseVariableDeclaration"); |
7776 ASSERT(IsIdentifier()); | 7434 ASSERT(IsIdentifier()); |
7777 const TokenPosition ident_pos = TokenPos(); | 7435 const TokenPosition ident_pos = TokenPos(); |
7778 const String& ident = *CurrentLiteral(); | 7436 const String& ident = *CurrentLiteral(); |
7779 ConsumeToken(); // Variable identifier. | 7437 ConsumeToken(); // Variable identifier. |
7780 const TokenPosition assign_pos = TokenPos(); | 7438 const TokenPosition assign_pos = TokenPos(); |
7781 AstNode* initialization = NULL; | 7439 AstNode* initialization = NULL; |
7782 LocalVariable* variable = NULL; | 7440 LocalVariable* variable = NULL; |
7783 if (CurrentToken() == Token::kASSIGN) { | 7441 if (CurrentToken() == Token::kASSIGN) { |
7784 // Variable initialization. | 7442 // Variable initialization. |
7785 ConsumeToken(); | 7443 ConsumeToken(); |
7786 AstNode* expr = ParseAwaitableExpr( | 7444 AstNode* expr = |
7787 is_const, kConsumeCascades, await_preamble); | 7445 ParseAwaitableExpr(is_const, kConsumeCascades, await_preamble); |
7788 const TokenPosition expr_end_pos = TokenPos(); | 7446 const TokenPosition expr_end_pos = TokenPos(); |
7789 variable = new(Z) LocalVariable( | 7447 variable = new (Z) LocalVariable(ident_pos, expr_end_pos, ident, type); |
7790 ident_pos, | 7448 initialization = new (Z) StoreLocalNode(assign_pos, variable, expr); |
7791 expr_end_pos, | |
7792 ident, | |
7793 type); | |
7794 initialization = new(Z) StoreLocalNode( | |
7795 assign_pos, variable, expr); | |
7796 if (is_const) { | 7449 if (is_const) { |
7797 ASSERT(expr->IsLiteralNode()); | 7450 ASSERT(expr->IsLiteralNode()); |
7798 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 7451 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
7799 } | 7452 } |
7800 } else if (is_final || is_const) { | 7453 } else if (is_final || is_const) { |
7801 ReportError(ident_pos, | 7454 ReportError(ident_pos, |
7802 "missing initialization of 'final' or 'const' variable"); | 7455 "missing initialization of 'final' or 'const' variable"); |
7803 } else { | 7456 } else { |
7804 // Initialize variable with null. | 7457 // Initialize variable with null. |
7805 variable = new(Z) LocalVariable( | 7458 variable = new (Z) LocalVariable(ident_pos, assign_pos, ident, type); |
7806 ident_pos, | 7459 AstNode* null_expr = |
7807 assign_pos, | 7460 new (Z) LiteralNode(ident_pos, Object::null_instance()); |
7808 ident, | 7461 initialization = new (Z) StoreLocalNode(ident_pos, variable, null_expr); |
7809 type); | |
7810 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance()); | |
7811 initialization = new(Z) StoreLocalNode( | |
7812 ident_pos, variable, null_expr); | |
7813 } | 7462 } |
7814 | 7463 |
7815 ASSERT(current_block_ != NULL); | 7464 ASSERT(current_block_ != NULL); |
7816 const TokenPosition previous_pos = | 7465 const TokenPosition previous_pos = |
7817 current_block_->scope->PreviousReferencePos(ident); | 7466 current_block_->scope->PreviousReferencePos(ident); |
7818 if (previous_pos.IsReal()) { | 7467 if (previous_pos.IsReal()) { |
7819 ASSERT(!script_.IsNull()); | 7468 ASSERT(!script_.IsNull()); |
7820 if (previous_pos > ident_pos) { | 7469 if (previous_pos > ident_pos) { |
7821 ReportError(ident_pos, | 7470 ReportError(ident_pos, "initializer of '%s' may not refer to itself", |
7822 "initializer of '%s' may not refer to itself", | |
7823 ident.ToCString()); | 7471 ident.ToCString()); |
7824 | 7472 |
7825 } else { | 7473 } else { |
7826 intptr_t line_number; | 7474 intptr_t line_number; |
7827 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7475 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
7828 ReportError(ident_pos, | 7476 ReportError(ident_pos, "identifier '%s' previously used in line %" Pd "", |
7829 "identifier '%s' previously used in line %" Pd "", | 7477 ident.ToCString(), line_number); |
7830 ident.ToCString(), | |
7831 line_number); | |
7832 } | 7478 } |
7833 } | 7479 } |
7834 | 7480 |
7835 // Add variable to scope after parsing the initalizer expression. | 7481 // Add variable to scope after parsing the initalizer expression. |
7836 // The expression must not be able to refer to the variable. | 7482 // The expression must not be able to refer to the variable. |
7837 if (!current_block_->scope->AddVariable(variable)) { | 7483 if (!current_block_->scope->AddVariable(variable)) { |
7838 LocalVariable* existing_var = | 7484 LocalVariable* existing_var = |
7839 current_block_->scope->LookupVariable(variable->name(), true); | 7485 current_block_->scope->LookupVariable(variable->name(), true); |
7840 ASSERT(existing_var != NULL); | 7486 ASSERT(existing_var != NULL); |
7841 // Use before define cases have already been detected and reported above. | 7487 // Use before define cases have already been detected and reported above. |
(...skipping 28 matching lines...) Expand all Loading... |
7870 if (type_is_optional) { | 7516 if (type_is_optional) { |
7871 return Type::DynamicType(); | 7517 return Type::DynamicType(); |
7872 } else { | 7518 } else { |
7873 ReportError("type name expected"); | 7519 ReportError("type name expected"); |
7874 } | 7520 } |
7875 } | 7521 } |
7876 if (type_is_optional) { | 7522 if (type_is_optional) { |
7877 Token::Kind follower = LookaheadToken(1); | 7523 Token::Kind follower = LookaheadToken(1); |
7878 // We have an identifier followed by a 'follower' token. | 7524 // We have an identifier followed by a 'follower' token. |
7879 // We either parse a type or return now. | 7525 // We either parse a type or return now. |
7880 if ((follower != Token::kLT) && // Parameterized type. | 7526 if ((follower != Token::kLT) && // Parameterized type. |
7881 (follower != Token::kPERIOD) && // Qualified class name of type. | 7527 (follower != Token::kPERIOD) && // Qualified class name of type. |
7882 !Token::IsIdentifier(follower) && // Variable name following a type. | 7528 !Token::IsIdentifier(follower) && // Variable name following a type. |
7883 (follower != Token::kTHIS)) { // Field parameter following a type. | 7529 (follower != Token::kTHIS)) { // Field parameter following a type. |
7884 return Type::DynamicType(); | 7530 return Type::DynamicType(); |
7885 } | 7531 } |
7886 } | 7532 } |
7887 return ParseType(finalization); | 7533 return ParseType(finalization); |
7888 } | 7534 } |
7889 | 7535 |
7890 | 7536 |
7891 // Returns ast nodes of the variable initialization. Variables without an | 7537 // Returns ast nodes of the variable initialization. Variables without an |
7892 // explicit initializer are initialized to null. If several variables are | 7538 // explicit initializer are initialized to null. If several variables are |
7893 // declared, the individual initializers are collected in a sequence node. | 7539 // declared, the individual initializers are collected in a sequence node. |
7894 AstNode* Parser::ParseVariableDeclarationList() { | 7540 AstNode* Parser::ParseVariableDeclarationList() { |
7895 TRACE_PARSER("ParseVariableDeclarationList"); | 7541 TRACE_PARSER("ParseVariableDeclarationList"); |
7896 SkipMetadata(); | 7542 SkipMetadata(); |
7897 bool is_final = (CurrentToken() == Token::kFINAL); | 7543 bool is_final = (CurrentToken() == Token::kFINAL); |
7898 bool is_const = (CurrentToken() == Token::kCONST); | 7544 bool is_const = (CurrentToken() == Token::kCONST); |
7899 const AbstractType& type = AbstractType::ZoneHandle(Z, | 7545 const AbstractType& type = AbstractType::ZoneHandle( |
7900 ParseConstFinalVarOrType(I->type_checks() ? | 7546 Z, |
7901 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); | 7547 ParseConstFinalVarOrType(I->type_checks() ? ClassFinalizer::kCanonicalize |
| 7548 : ClassFinalizer::kIgnore)); |
7902 if (!IsIdentifier()) { | 7549 if (!IsIdentifier()) { |
7903 ReportError("identifier expected"); | 7550 ReportError("identifier expected"); |
7904 } | 7551 } |
7905 | 7552 |
7906 SequenceNode* preamble = NULL; | 7553 SequenceNode* preamble = NULL; |
7907 AstNode* initializers = | 7554 AstNode* initializers = |
7908 ParseVariableDeclaration(type, is_final, is_const, &preamble); | 7555 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
7909 ASSERT(initializers != NULL); | 7556 ASSERT(initializers != NULL); |
7910 if (preamble != NULL) { | 7557 if (preamble != NULL) { |
7911 preamble->Add(initializers); | 7558 preamble->Add(initializers); |
7912 initializers = preamble; | 7559 initializers = preamble; |
7913 } | 7560 } |
7914 while (CurrentToken() == Token::kCOMMA) { | 7561 while (CurrentToken() == Token::kCOMMA) { |
7915 ConsumeToken(); | 7562 ConsumeToken(); |
7916 if (!IsIdentifier()) { | 7563 if (!IsIdentifier()) { |
7917 ReportError("identifier expected after comma"); | 7564 ReportError("identifier expected after comma"); |
7918 } | 7565 } |
7919 // We have a second initializer. Allocate a sequence node now. | 7566 // We have a second initializer. Allocate a sequence node now. |
7920 // The sequence does not own the current scope. Set its own scope to NULL. | 7567 // The sequence does not own the current scope. Set its own scope to NULL. |
7921 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), | 7568 SequenceNode* sequence = |
7922 initializers, | 7569 NodeAsSequenceNode(initializers->token_pos(), initializers, NULL); |
7923 NULL); | |
7924 preamble = NULL; | 7570 preamble = NULL; |
7925 AstNode* declaration = ParseVariableDeclaration( | 7571 AstNode* declaration = |
7926 type, is_final, is_const, &preamble); | 7572 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
7927 if (preamble != NULL) { | 7573 if (preamble != NULL) { |
7928 sequence->Add(preamble); | 7574 sequence->Add(preamble); |
7929 } | 7575 } |
7930 sequence->Add(declaration); | 7576 sequence->Add(declaration); |
7931 initializers = sequence; | 7577 initializers = sequence; |
7932 } | 7578 } |
7933 return initializers; | 7579 return initializers; |
7934 } | 7580 } |
7935 | 7581 |
7936 | 7582 |
(...skipping 29 matching lines...) Expand all Loading... |
7966 // before this declaration. | 7612 // before this declaration. |
7967 ASSERT(current_block_ != NULL); | 7613 ASSERT(current_block_ != NULL); |
7968 const TokenPosition previous_pos = | 7614 const TokenPosition previous_pos = |
7969 current_block_->scope->PreviousReferencePos(*function_name); | 7615 current_block_->scope->PreviousReferencePos(*function_name); |
7970 if (previous_pos.IsReal()) { | 7616 if (previous_pos.IsReal()) { |
7971 ASSERT(!script_.IsNull()); | 7617 ASSERT(!script_.IsNull()); |
7972 intptr_t line_number; | 7618 intptr_t line_number; |
7973 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7619 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
7974 ReportError(function_name_pos, | 7620 ReportError(function_name_pos, |
7975 "identifier '%s' previously used in line %" Pd "", | 7621 "identifier '%s' previously used in line %" Pd "", |
7976 function_name->ToCString(), | 7622 function_name->ToCString(), line_number); |
7977 line_number); | |
7978 } | 7623 } |
7979 } | 7624 } |
7980 | 7625 |
7981 // Check whether we have parsed this closure function before, in a previous | 7626 // Check whether we have parsed this closure function before, in a previous |
7982 // compilation. If so, reuse the function object, else create a new one | 7627 // compilation. If so, reuse the function object, else create a new one |
7983 // and register it in the current class. | 7628 // and register it in the current class. |
7984 // Note that we cannot share the same closure function between the closurized | 7629 // Note that we cannot share the same closure function between the closurized |
7985 // and non-closurized versions of the same parent function. | 7630 // and non-closurized versions of the same parent function. |
7986 Function& function = Function::ZoneHandle(Z); | 7631 Function& function = Function::ZoneHandle(Z); |
7987 bool found_func = true; | 7632 bool found_func = true; |
7988 // TODO(hausner): There could be two different closures at the given | 7633 // TODO(hausner): There could be two different closures at the given |
7989 // function_pos, one enclosed in a closurized function and one enclosed in the | 7634 // function_pos, one enclosed in a closurized function and one enclosed in the |
7990 // non-closurized version of this same function. | 7635 // non-closurized version of this same function. |
7991 function = I->LookupClosureFunction(innermost_function(), function_pos); | 7636 function = I->LookupClosureFunction(innermost_function(), function_pos); |
7992 if (function.IsNull()) { | 7637 if (function.IsNull()) { |
7993 // The function will be registered in the lookup table by the | 7638 // The function will be registered in the lookup table by the |
7994 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 7639 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
7995 // function has been properly setup. | 7640 // function has been properly setup. |
7996 found_func = false; | 7641 found_func = false; |
7997 function = Function::NewClosureFunction(*function_name, | 7642 function = Function::NewClosureFunction(*function_name, |
7998 innermost_function(), | 7643 innermost_function(), function_pos); |
7999 function_pos); | |
8000 function.set_result_type(result_type); | 7644 function.set_result_type(result_type); |
8001 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 7645 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
8002 library_.AddFunctionMetadata(function, metadata_pos); | 7646 library_.AddFunctionMetadata(function, metadata_pos); |
8003 } | 7647 } |
8004 } | 7648 } |
8005 | 7649 |
8006 ASSERT(function.parent_function() == innermost_function_.raw()); | 7650 ASSERT(function.parent_function() == innermost_function_.raw()); |
8007 innermost_function_ = function.raw(); | 7651 innermost_function_ = function.raw(); |
8008 | 7652 |
8009 if (CurrentToken() == Token::kLT) { | 7653 if (CurrentToken() == Token::kLT) { |
8010 if (!FLAG_generic_method_syntax) { | 7654 if (!FLAG_generic_method_syntax) { |
8011 ReportError("generic functions not supported"); | 7655 ReportError("generic functions not supported"); |
8012 } | 7656 } |
8013 if (!found_func) { | 7657 if (!found_func) { |
8014 ParseTypeParameters(false); // Not parameterizing class, but function. | 7658 ParseTypeParameters(false); // Not parameterizing class, but function. |
8015 } else { | 7659 } else { |
8016 TryParseTypeParameters(); | 7660 TryParseTypeParameters(); |
8017 } | 7661 } |
8018 } | 7662 } |
8019 | 7663 |
8020 if (!found_func && !result_type.IsFinalized()) { | 7664 if (!found_func && !result_type.IsFinalized()) { |
8021 // Now that type parameters are declared, the result type can be resolved | 7665 // Now that type parameters are declared, the result type can be resolved |
8022 // and finalized. | 7666 // and finalized. |
8023 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); | 7667 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); |
8024 result_type = ClassFinalizer::FinalizeType( | 7668 result_type = ClassFinalizer::FinalizeType(current_class(), result_type, |
8025 current_class(), result_type, ClassFinalizer::kCanonicalize); | 7669 ClassFinalizer::kCanonicalize); |
8026 function.set_result_type(result_type); | 7670 function.set_result_type(result_type); |
8027 } | 7671 } |
8028 | 7672 |
8029 CheckToken(Token::kLPAREN); | 7673 CheckToken(Token::kLPAREN); |
8030 | 7674 |
8031 // The function type needs to be finalized at compile time, since the closure | 7675 // The function type needs to be finalized at compile time, since the closure |
8032 // may be type checked at run time when assigned to a function variable, | 7676 // may be type checked at run time when assigned to a function variable, |
8033 // passed as a function argument, or returned as a function result. | 7677 // passed as a function argument, or returned as a function result. |
8034 | 7678 |
8035 LocalVariable* function_variable = NULL; | 7679 LocalVariable* function_variable = NULL; |
8036 Type& function_type = Type::ZoneHandle(Z); | 7680 Type& function_type = Type::ZoneHandle(Z); |
8037 if (variable_name != NULL) { | 7681 if (variable_name != NULL) { |
8038 // Since the function type depends on the signature of the closure function, | 7682 // Since the function type depends on the signature of the closure function, |
8039 // it cannot be determined before the formal parameter list of the closure | 7683 // it cannot be determined before the formal parameter list of the closure |
8040 // function is parsed. Therefore, we set the function type to a new | 7684 // function is parsed. Therefore, we set the function type to a new |
8041 // function type to be patched after the actual type is known. | 7685 // function type to be patched after the actual type is known. |
8042 // We temporarily use the Closure class as scope class. | 7686 // We temporarily use the Closure class as scope class. |
8043 const Class& unknown_scope_class = Class::Handle(Z, | 7687 const Class& unknown_scope_class = |
8044 I->object_store()->closure_class()); | 7688 Class::Handle(Z, I->object_store()->closure_class()); |
8045 function_type = Type::New(unknown_scope_class, | 7689 function_type = |
8046 TypeArguments::Handle(Z), | 7690 Type::New(unknown_scope_class, TypeArguments::Handle(Z), function_pos); |
8047 function_pos); | |
8048 function_type.set_signature(function); | 7691 function_type.set_signature(function); |
8049 function_type.SetIsFinalized(); // No finalization needed. | 7692 function_type.SetIsFinalized(); // No finalization needed. |
8050 | 7693 |
8051 // Add the function variable to the scope before parsing the function in | 7694 // Add the function variable to the scope before parsing the function in |
8052 // order to allow self reference from inside the function. | 7695 // order to allow self reference from inside the function. |
8053 function_variable = new(Z) LocalVariable(function_name_pos, | 7696 function_variable = new (Z) LocalVariable(function_name_pos, function_pos, |
8054 function_pos, | 7697 *variable_name, function_type); |
8055 *variable_name, | |
8056 function_type); | |
8057 function_variable->set_is_final(); | 7698 function_variable->set_is_final(); |
8058 ASSERT(current_block_ != NULL); | 7699 ASSERT(current_block_ != NULL); |
8059 ASSERT(current_block_->scope != NULL); | 7700 ASSERT(current_block_->scope != NULL); |
8060 if (!current_block_->scope->AddVariable(function_variable)) { | 7701 if (!current_block_->scope->AddVariable(function_variable)) { |
8061 LocalVariable* existing_var = | 7702 LocalVariable* existing_var = current_block_->scope->LookupVariable( |
8062 current_block_->scope->LookupVariable(function_variable->name(), | 7703 function_variable->name(), true); |
8063 true); | |
8064 ASSERT(existing_var != NULL); | 7704 ASSERT(existing_var != NULL); |
8065 // Use before define cases have already been detected and reported above. | 7705 // Use before define cases have already been detected and reported above. |
8066 ASSERT(existing_var->owner() == current_block_->scope); | 7706 ASSERT(existing_var->owner() == current_block_->scope); |
8067 ReportError(function_pos, "identifier '%s' already defined", | 7707 ReportError(function_pos, "identifier '%s' already defined", |
8068 function_variable->name().ToCString()); | 7708 function_variable->name().ToCString()); |
8069 } | 7709 } |
8070 } | 7710 } |
8071 | 7711 |
8072 Type& signature_type = Type::ZoneHandle(Z); | 7712 Type& signature_type = Type::ZoneHandle(Z); |
8073 SequenceNode* statements = NULL; | 7713 SequenceNode* statements = NULL; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8117 CaptureInstantiator(); | 7757 CaptureInstantiator(); |
8118 } | 7758 } |
8119 | 7759 |
8120 // A local signature type itself cannot be malformed or malbounded, only its | 7760 // A local signature type itself cannot be malformed or malbounded, only its |
8121 // signature function's result type or parameter types may be. | 7761 // signature function's result type or parameter types may be. |
8122 ASSERT(!signature_type.IsMalformed()); | 7762 ASSERT(!signature_type.IsMalformed()); |
8123 ASSERT(!signature_type.IsMalbounded()); | 7763 ASSERT(!signature_type.IsMalbounded()); |
8124 | 7764 |
8125 if (variable_name != NULL) { | 7765 if (variable_name != NULL) { |
8126 // Patch the function type of the variable now that the signature is known. | 7766 // Patch the function type of the variable now that the signature is known. |
8127 function_type.set_type_class( | 7767 function_type.set_type_class(Class::Handle(Z, signature_type.type_class())); |
8128 Class::Handle(Z, signature_type.type_class())); | |
8129 function_type.set_arguments( | 7768 function_type.set_arguments( |
8130 TypeArguments::Handle(Z, signature_type.arguments())); | 7769 TypeArguments::Handle(Z, signature_type.arguments())); |
8131 ASSERT(function_type.signature() == function.raw()); | 7770 ASSERT(function_type.signature() == function.raw()); |
8132 | 7771 |
8133 // The function type was initially marked as instantiated, but it may | 7772 // The function type was initially marked as instantiated, but it may |
8134 // actually be uninstantiated. | 7773 // actually be uninstantiated. |
8135 function_type.ResetIsFinalized(); | 7774 function_type.ResetIsFinalized(); |
8136 | 7775 |
8137 // The function variable type should have been patched above. | 7776 // The function variable type should have been patched above. |
8138 ASSERT((function_variable == NULL) || | 7777 ASSERT((function_variable == NULL) || |
(...skipping 13 matching lines...) Expand all Loading... |
8152 // allocation information in a Scope object stored in the function object. | 7791 // allocation information in a Scope object stored in the function object. |
8153 // This Scope object is then provided to the compiler when compiling the local | 7792 // This Scope object is then provided to the compiler when compiling the local |
8154 // function. It would be too early to record the captured variables here, | 7793 // function. It would be too early to record the captured variables here, |
8155 // since further closure functions may capture more variables. | 7794 // since further closure functions may capture more variables. |
8156 // This Scope object is constructed after all variables have been allocated. | 7795 // This Scope object is constructed after all variables have been allocated. |
8157 // The local scope of the parsed function can be pruned, since contained | 7796 // The local scope of the parsed function can be pruned, since contained |
8158 // variables are not relevant for the compilation of the enclosing function. | 7797 // variables are not relevant for the compilation of the enclosing function. |
8159 // This pruning is done by omitting to hook the local scope in its parent | 7798 // This pruning is done by omitting to hook the local scope in its parent |
8160 // scope in the constructor of LocalScope. | 7799 // scope in the constructor of LocalScope. |
8161 AstNode* closure = | 7800 AstNode* closure = |
8162 new(Z) ClosureNode(function_pos, function, NULL, | 7801 new (Z) ClosureNode(function_pos, function, NULL, |
8163 statements != NULL ? statements->scope() : NULL); | 7802 statements != NULL ? statements->scope() : NULL); |
8164 | 7803 |
8165 ASSERT(innermost_function_.raw() == function.raw()); | 7804 ASSERT(innermost_function_.raw() == function.raw()); |
8166 innermost_function_ = function.parent_function(); | 7805 innermost_function_ = function.parent_function(); |
8167 | 7806 |
8168 if (function_variable == NULL) { | 7807 if (function_variable == NULL) { |
8169 ASSERT(is_literal); | 7808 ASSERT(is_literal); |
8170 return closure; | 7809 return closure; |
8171 } else { | 7810 } else { |
8172 AstNode* initialization = new(Z) StoreLocalNode( | 7811 AstNode* initialization = |
8173 function_pos, function_variable, closure); | 7812 new (Z) StoreLocalNode(function_pos, function_variable, closure); |
8174 return initialization; | 7813 return initialization; |
8175 } | 7814 } |
8176 } | 7815 } |
8177 | 7816 |
8178 | 7817 |
8179 // Returns true if the current and next tokens can be parsed as type | 7818 // Returns true if the current and next tokens can be parsed as type |
8180 // parameters. Current token position is not saved and restored. | 7819 // parameters. Current token position is not saved and restored. |
8181 bool Parser::TryParseTypeParameters() { | 7820 bool Parser::TryParseTypeParameters() { |
8182 ASSERT(CurrentToken() == Token::kLT); | 7821 ASSERT(CurrentToken() == Token::kLT); |
8183 int nesting_level = 0; | 7822 int nesting_level = 0; |
8184 do { | 7823 do { |
8185 Token::Kind ct = CurrentToken(); | 7824 Token::Kind ct = CurrentToken(); |
8186 if (ct == Token::kLT) { | 7825 if (ct == Token::kLT) { |
8187 nesting_level++; | 7826 nesting_level++; |
8188 } else if (ct == Token::kGT) { | 7827 } else if (ct == Token::kGT) { |
8189 nesting_level--; | 7828 nesting_level--; |
8190 } else if (ct == Token::kSHR) { | 7829 } else if (ct == Token::kSHR) { |
8191 nesting_level -= 2; | 7830 nesting_level -= 2; |
8192 } else if (ct == Token::kIDENT) { | 7831 } else if (ct == Token::kIDENT) { |
8193 // Check to see if it is a qualified identifier. | 7832 // Check to see if it is a qualified identifier. |
8194 if (LookaheadToken(1) == Token::kPERIOD) { | 7833 if (LookaheadToken(1) == Token::kPERIOD) { |
8195 // Consume the identifier, the period will be consumed below. | 7834 // Consume the identifier, the period will be consumed below. |
8196 ConsumeToken(); | 7835 ConsumeToken(); |
8197 } | 7836 } |
8198 } else if ((ct != Token::kCOMMA) && | 7837 } else if ((ct != Token::kCOMMA) && (ct != Token::kEXTENDS) && |
8199 (ct != Token::kEXTENDS) && | |
8200 (!FLAG_generic_method_syntax || (ct != Token::kSUPER))) { | 7838 (!FLAG_generic_method_syntax || (ct != Token::kSUPER))) { |
8201 // We are looking at something other than type parameters. | 7839 // We are looking at something other than type parameters. |
8202 return false; | 7840 return false; |
8203 } | 7841 } |
8204 ConsumeToken(); | 7842 ConsumeToken(); |
8205 } while (nesting_level > 0); | 7843 } while (nesting_level > 0); |
8206 if (nesting_level < 0) { | 7844 if (nesting_level < 0) { |
8207 return false; | 7845 return false; |
8208 } | 7846 } |
8209 return true; | 7847 return true; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8322 *value = Bool::False().raw(); | 7960 *value = Bool::False().raw(); |
8323 return true; | 7961 return true; |
8324 } | 7962 } |
8325 return false; | 7963 return false; |
8326 } | 7964 } |
8327 | 7965 |
8328 | 7966 |
8329 // Returns true if the current token is kIDENT or a pseudo-keyword. | 7967 // Returns true if the current token is kIDENT or a pseudo-keyword. |
8330 bool Parser::IsIdentifier() { | 7968 bool Parser::IsIdentifier() { |
8331 return Token::IsIdentifier(CurrentToken()) && | 7969 return Token::IsIdentifier(CurrentToken()) && |
8332 !(await_is_keyword_ && | 7970 !(await_is_keyword_ && |
8333 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || | 7971 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || |
8334 (CurrentLiteral()->raw() == Symbols::Async().raw()) || | 7972 (CurrentLiteral()->raw() == Symbols::Async().raw()) || |
8335 (CurrentLiteral()->raw() == Symbols::YieldKw().raw()))); | 7973 (CurrentLiteral()->raw() == Symbols::YieldKw().raw()))); |
8336 } | 7974 } |
8337 | 7975 |
8338 | 7976 |
8339 bool Parser::IsSymbol(const String& symbol) { | 7977 bool Parser::IsSymbol(const String& symbol) { |
8340 return (CurrentLiteral()->raw() == symbol.raw()) && | 7978 return (CurrentLiteral()->raw() == symbol.raw()) && |
8341 (CurrentToken() == Token::kIDENT); | 7979 (CurrentToken() == Token::kIDENT); |
8342 } | 7980 } |
8343 | 7981 |
8344 | 7982 |
8345 // Returns true if the next tokens can be parsed as a an optionally | 7983 // Returns true if the next tokens can be parsed as a an optionally |
8346 // qualified identifier: [ident '.'] ident. | 7984 // qualified identifier: [ident '.'] ident. |
8347 // Current token position is not restored. | 7985 // Current token position is not restored. |
8348 bool Parser::TryParseQualIdent() { | 7986 bool Parser::TryParseQualIdent() { |
8349 if (CurrentToken() != Token::kIDENT) { | 7987 if (CurrentToken() != Token::kIDENT) { |
8350 return false; | 7988 return false; |
8351 } | 7989 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8392 | 8030 |
8393 // Look ahead to detect whether the next tokens should be parsed as | 8031 // Look ahead to detect whether the next tokens should be parsed as |
8394 // a variable declaration. Ignores optional metadata. | 8032 // a variable declaration. Ignores optional metadata. |
8395 // Returns true if we detect the token pattern: | 8033 // Returns true if we detect the token pattern: |
8396 // 'var' | 8034 // 'var' |
8397 // | 'final' | 8035 // | 'final' |
8398 // | const [type] ident (';' | '=' | ',') | 8036 // | const [type] ident (';' | '=' | ',') |
8399 // | type ident (';' | '=' | ',') | 8037 // | type ident (';' | '=' | ',') |
8400 // Token position remains unchanged. | 8038 // Token position remains unchanged. |
8401 bool Parser::IsVariableDeclaration() { | 8039 bool Parser::IsVariableDeclaration() { |
8402 if ((CurrentToken() == Token::kVAR) || | 8040 if ((CurrentToken() == Token::kVAR) || (CurrentToken() == Token::kFINAL)) { |
8403 (CurrentToken() == Token::kFINAL)) { | |
8404 return true; | 8041 return true; |
8405 } | 8042 } |
8406 // Skip optional metadata. | 8043 // Skip optional metadata. |
8407 if (CurrentToken() == Token::kAT) { | 8044 if (CurrentToken() == Token::kAT) { |
8408 const TokenPosition saved_pos = TokenPos(); | 8045 const TokenPosition saved_pos = TokenPos(); |
8409 SkipMetadata(); | 8046 SkipMetadata(); |
8410 const bool is_var_decl = IsVariableDeclaration(); | 8047 const bool is_var_decl = IsVariableDeclaration(); |
8411 SetPosition(saved_pos); | 8048 SetPosition(saved_pos); |
8412 return is_var_decl; | 8049 return is_var_decl; |
8413 } | 8050 } |
8414 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { | 8051 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { |
8415 // Not a legal type identifier or const keyword or metadata. | 8052 // Not a legal type identifier or const keyword or metadata. |
8416 return false; | 8053 return false; |
8417 } | 8054 } |
8418 const TokenPosition saved_pos = TokenPos(); | 8055 const TokenPosition saved_pos = TokenPos(); |
8419 bool is_var_decl = false; | 8056 bool is_var_decl = false; |
8420 bool have_type = false; | 8057 bool have_type = false; |
8421 if (CurrentToken() == Token::kCONST) { | 8058 if (CurrentToken() == Token::kCONST) { |
8422 ConsumeToken(); | 8059 ConsumeToken(); |
8423 have_type = true; // Type is dynamic. | 8060 have_type = true; // Type is dynamic. |
8424 } | 8061 } |
8425 if (IsIdentifier()) { // Type or variable name. | 8062 if (IsIdentifier()) { // Type or variable name. |
8426 Token::Kind follower = LookaheadToken(1); | 8063 Token::Kind follower = LookaheadToken(1); |
8427 if ((follower == Token::kLT) || // Parameterized type. | 8064 if ((follower == Token::kLT) || // Parameterized type. |
8428 (follower == Token::kPERIOD) || // Qualified class name of type. | 8065 (follower == Token::kPERIOD) || // Qualified class name of type. |
8429 Token::IsIdentifier(follower)) { // Variable name following a type. | 8066 Token::IsIdentifier(follower)) { // Variable name following a type. |
8430 // We see the beginning of something that could be a type. | 8067 // We see the beginning of something that could be a type. |
8431 const TokenPosition type_pos = TokenPos(); | 8068 const TokenPosition type_pos = TokenPos(); |
8432 if (TryParseOptionalType()) { | 8069 if (TryParseOptionalType()) { |
8433 have_type = true; | 8070 have_type = true; |
8434 } else { | 8071 } else { |
8435 SetPosition(type_pos); | 8072 SetPosition(type_pos); |
8436 } | 8073 } |
8437 } | 8074 } |
8438 if (have_type && IsIdentifier()) { | 8075 if (have_type && IsIdentifier()) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8491 return false; | 8128 return false; |
8492 } | 8129 } |
8493 | 8130 |
8494 // Optional type, function name and optinal type parameters are parsed. | 8131 // Optional type, function name and optinal type parameters are parsed. |
8495 if (CurrentToken() != Token::kLPAREN) { | 8132 if (CurrentToken() != Token::kLPAREN) { |
8496 return false; | 8133 return false; |
8497 } | 8134 } |
8498 | 8135 |
8499 // Check parameter list and the following token. | 8136 // Check parameter list and the following token. |
8500 SkipToMatchingParenthesis(); | 8137 SkipToMatchingParenthesis(); |
8501 if ((CurrentToken() == Token::kLBRACE) || | 8138 if ((CurrentToken() == Token::kLBRACE) || (CurrentToken() == Token::kARROW) || |
8502 (CurrentToken() == Token::kARROW) || | 8139 (is_top_level_ && IsSymbol(Symbols::Native())) || is_external || |
8503 (is_top_level_ && IsSymbol(Symbols::Native())) || | 8140 IsSymbol(Symbols::Async()) || IsSymbol(Symbols::Sync())) { |
8504 is_external || | |
8505 IsSymbol(Symbols::Async()) || | |
8506 IsSymbol(Symbols::Sync())) { | |
8507 return true; | 8141 return true; |
8508 } | 8142 } |
8509 return false; | 8143 return false; |
8510 } | 8144 } |
8511 | 8145 |
8512 | 8146 |
8513 bool Parser::IsTopLevelAccessor() { | 8147 bool Parser::IsTopLevelAccessor() { |
8514 const TokenPosScope saved_pos(this); | 8148 const TokenPosScope saved_pos(this); |
8515 if (CurrentToken() == Token::kEXTERNAL) { | 8149 if (CurrentToken() == Token::kEXTERNAL) { |
8516 ConsumeToken(); | 8150 ConsumeToken(); |
(...skipping 21 matching lines...) Expand all Loading... |
8538 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) { | 8172 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) { |
8539 return false; | 8173 return false; |
8540 } | 8174 } |
8541 if (CurrentToken() != Token::kLPAREN) { | 8175 if (CurrentToken() != Token::kLPAREN) { |
8542 return false; | 8176 return false; |
8543 } | 8177 } |
8544 SkipToMatchingParenthesis(); | 8178 SkipToMatchingParenthesis(); |
8545 ParseFunctionModifier(); | 8179 ParseFunctionModifier(); |
8546 if ((CurrentToken() == Token::kLBRACE) || | 8180 if ((CurrentToken() == Token::kLBRACE) || |
8547 (CurrentToken() == Token::kARROW)) { | 8181 (CurrentToken() == Token::kARROW)) { |
8548 return true; | 8182 return true; |
8549 } | 8183 } |
8550 } | 8184 } |
8551 return false; | 8185 return false; |
8552 } | 8186 } |
8553 | 8187 |
8554 | 8188 |
8555 // Current token position is the token after the opening ( of the for | 8189 // Current token position is the token after the opening ( of the for |
8556 // statement. Returns true if we recognize a for ( .. in expr) | 8190 // statement. Returns true if we recognize a for ( .. in expr) |
8557 // statement. | 8191 // statement. |
8558 bool Parser::IsForInStatement() { | 8192 bool Parser::IsForInStatement() { |
8559 const TokenPosScope saved_pos(this); | 8193 const TokenPosScope saved_pos(this); |
8560 // Allow const modifier as well when recognizing a for-in statement | 8194 // Allow const modifier as well when recognizing a for-in statement |
8561 // pattern. We will get an error later if the loop variable is | 8195 // pattern. We will get an error later if the loop variable is |
8562 // declared with const. | 8196 // declared with const. |
8563 if (CurrentToken() == Token::kVAR || | 8197 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL || |
8564 CurrentToken() == Token::kFINAL || | |
8565 CurrentToken() == Token::kCONST) { | 8198 CurrentToken() == Token::kCONST) { |
8566 ConsumeToken(); | 8199 ConsumeToken(); |
8567 } | 8200 } |
8568 if (IsIdentifier()) { | 8201 if (IsIdentifier()) { |
8569 if (LookaheadToken(1) == Token::kIN) { | 8202 if (LookaheadToken(1) == Token::kIN) { |
8570 return true; | 8203 return true; |
8571 } else if (TryParseOptionalType()) { | 8204 } else if (TryParseOptionalType()) { |
8572 if (IsIdentifier()) { | 8205 if (IsIdentifier()) { |
8573 ConsumeToken(); | 8206 ConsumeToken(); |
8574 } | 8207 } |
8575 return CurrentToken() == Token::kIN; | 8208 return CurrentToken() == Token::kIN; |
8576 } | 8209 } |
8577 } | 8210 } |
8578 return false; | 8211 return false; |
8579 } | 8212 } |
8580 | 8213 |
8581 | 8214 |
8582 static bool ContainsAbruptCompletingStatement(SequenceNode* seq); | 8215 static bool ContainsAbruptCompletingStatement(SequenceNode* seq); |
8583 | 8216 |
8584 static bool IsAbruptCompleting(AstNode* statement) { | 8217 static bool IsAbruptCompleting(AstNode* statement) { |
8585 return statement->IsReturnNode() || | 8218 return statement->IsReturnNode() || statement->IsJumpNode() || |
8586 statement->IsJumpNode() || | 8219 statement->IsThrowNode() || |
8587 statement->IsThrowNode() || | |
8588 (statement->IsSequenceNode() && | 8220 (statement->IsSequenceNode() && |
8589 ContainsAbruptCompletingStatement(statement->AsSequenceNode())); | 8221 ContainsAbruptCompletingStatement(statement->AsSequenceNode())); |
8590 } | 8222 } |
8591 | 8223 |
8592 | 8224 |
8593 static bool ContainsAbruptCompletingStatement(SequenceNode* seq) { | 8225 static bool ContainsAbruptCompletingStatement(SequenceNode* seq) { |
8594 for (int i = 0; i < seq->length(); i++) { | 8226 for (int i = 0; i < seq->length(); i++) { |
8595 if (IsAbruptCompleting(seq->NodeAt(i))) { | 8227 if (IsAbruptCompleting(seq->NodeAt(i))) { |
8596 return true; | 8228 return true; |
8597 } | 8229 } |
8598 } | 8230 } |
8599 return false; | 8231 return false; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8669 ExpectToken(Token::kLPAREN); | 8301 ExpectToken(Token::kLPAREN); |
8670 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8302 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8671 ExpectToken(Token::kRPAREN); | 8303 ExpectToken(Token::kRPAREN); |
8672 const bool parsing_loop_body = false; | 8304 const bool parsing_loop_body = false; |
8673 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); | 8305 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); |
8674 SequenceNode* false_branch = NULL; | 8306 SequenceNode* false_branch = NULL; |
8675 if (CurrentToken() == Token::kELSE) { | 8307 if (CurrentToken() == Token::kELSE) { |
8676 ConsumeToken(); | 8308 ConsumeToken(); |
8677 false_branch = ParseNestedStatement(parsing_loop_body, NULL); | 8309 false_branch = ParseNestedStatement(parsing_loop_body, NULL); |
8678 } | 8310 } |
8679 AstNode* if_node = new(Z) IfNode( | 8311 AstNode* if_node = |
8680 if_pos, cond_expr, true_branch, false_branch); | 8312 new (Z) IfNode(if_pos, cond_expr, true_branch, false_branch); |
8681 if (label != NULL) { | 8313 if (label != NULL) { |
8682 current_block_->statements->Add(if_node); | 8314 current_block_->statements->Add(if_node); |
8683 SequenceNode* sequence = CloseBlock(); | 8315 SequenceNode* sequence = CloseBlock(); |
8684 sequence->set_label(label); | 8316 sequence->set_label(label); |
8685 if_node = sequence; | 8317 if_node = sequence; |
8686 } | 8318 } |
8687 return if_node; | 8319 return if_node; |
8688 } | 8320 } |
8689 | 8321 |
8690 | 8322 |
8691 // Return true if the type class of the given value implements the | 8323 // Return true if the type class of the given value implements the |
8692 // == operator. | 8324 // == operator. |
8693 static bool ImplementsEqualOperator(Zone* zone, const Instance& value) { | 8325 static bool ImplementsEqualOperator(Zone* zone, const Instance& value) { |
8694 Class& cls = Class::Handle(value.clazz()); | 8326 Class& cls = Class::Handle(value.clazz()); |
8695 const Function& equal_op = Function::Handle(zone, | 8327 const Function& equal_op = Function::Handle( |
| 8328 zone, |
8696 Resolver::ResolveDynamicAnyArgs(zone, cls, Symbols::EqualOperator())); | 8329 Resolver::ResolveDynamicAnyArgs(zone, cls, Symbols::EqualOperator())); |
8697 ASSERT(!equal_op.IsNull()); | 8330 ASSERT(!equal_op.IsNull()); |
8698 cls = equal_op.Owner(); | 8331 cls = equal_op.Owner(); |
8699 return !cls.IsObjectClass(); | 8332 return !cls.IsObjectClass(); |
8700 } | 8333 } |
8701 | 8334 |
8702 | 8335 |
8703 // Check that all case expressions are of the same type, either int, String, | 8336 // Check that all case expressions are of the same type, either int, String, |
8704 // or any other class that does not override the == operator. | 8337 // or any other class that does not override the == operator. |
8705 // The expressions are compile-time constants and are thus in the form | 8338 // The expressions are compile-time constants and are thus in the form |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8756 } | 8389 } |
8757 | 8390 |
8758 | 8391 |
8759 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 8392 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
8760 GrowableArray<LiteralNode*>* case_expr_values, | 8393 GrowableArray<LiteralNode*>* case_expr_values, |
8761 SourceLabel* case_label) { | 8394 SourceLabel* case_label) { |
8762 TRACE_PARSER("ParseCaseClause"); | 8395 TRACE_PARSER("ParseCaseClause"); |
8763 bool default_seen = false; | 8396 bool default_seen = false; |
8764 const TokenPosition case_pos = TokenPos(); | 8397 const TokenPosition case_pos = TokenPos(); |
8765 // The case expressions node sequence does not own the enclosing scope. | 8398 // The case expressions node sequence does not own the enclosing scope. |
8766 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); | 8399 SequenceNode* case_expressions = new (Z) SequenceNode(case_pos, NULL); |
8767 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 8400 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
8768 if (CurrentToken() == Token::kCASE) { | 8401 if (CurrentToken() == Token::kCASE) { |
8769 if (default_seen) { | 8402 if (default_seen) { |
8770 ReportError("default clause must be last case"); | 8403 ReportError("default clause must be last case"); |
8771 } | 8404 } |
8772 ConsumeToken(); // Keyword case. | 8405 ConsumeToken(); // Keyword case. |
8773 const TokenPosition expr_pos = TokenPos(); | 8406 const TokenPosition expr_pos = TokenPos(); |
8774 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); | 8407 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
8775 ASSERT(expr->IsLiteralNode()); | 8408 ASSERT(expr->IsLiteralNode()); |
8776 case_expr_values->Add(expr->AsLiteralNode()); | 8409 case_expr_values->Add(expr->AsLiteralNode()); |
8777 | 8410 |
8778 AstNode* switch_expr_load = new(Z) LoadLocalNode( | 8411 AstNode* switch_expr_load = |
8779 case_pos, switch_expr_value); | 8412 new (Z) LoadLocalNode(case_pos, switch_expr_value); |
8780 AstNode* case_comparison = new(Z) ComparisonNode( | 8413 AstNode* case_comparison = |
8781 expr_pos, Token::kEQ, expr, switch_expr_load); | 8414 new (Z) ComparisonNode(expr_pos, Token::kEQ, expr, switch_expr_load); |
8782 case_expressions->Add(case_comparison); | 8415 case_expressions->Add(case_comparison); |
8783 } else { | 8416 } else { |
8784 if (default_seen) { | 8417 if (default_seen) { |
8785 ReportError("only one default clause is allowed"); | 8418 ReportError("only one default clause is allowed"); |
8786 } | 8419 } |
8787 ConsumeToken(); // Keyword default. | 8420 ConsumeToken(); // Keyword default. |
8788 default_seen = true; | 8421 default_seen = true; |
8789 // The default case always succeeds. | 8422 // The default case always succeeds. |
8790 } | 8423 } |
8791 ExpectToken(Token::kCOLON); | 8424 ExpectToken(Token::kCOLON); |
(...skipping 12 matching lines...) Expand all Loading... |
8804 next_token = CurrentToken(); | 8437 next_token = CurrentToken(); |
8805 } | 8438 } |
8806 if (next_token == Token::kRBRACE) { | 8439 if (next_token == Token::kRBRACE) { |
8807 // End of switch statement. | 8440 // End of switch statement. |
8808 break; | 8441 break; |
8809 } | 8442 } |
8810 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 8443 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
8811 // End of this case clause. If there is a possible fall-through to | 8444 // End of this case clause. If there is a possible fall-through to |
8812 // the next case clause, throw an implicit FallThroughError. | 8445 // the next case clause, throw an implicit FallThroughError. |
8813 if (!abrupt_completing_seen) { | 8446 if (!abrupt_completing_seen) { |
8814 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); | 8447 ArgumentListNode* arguments = new (Z) ArgumentListNode(TokenPos()); |
8815 arguments->Add(new(Z) LiteralNode( | 8448 arguments->Add(new (Z) LiteralNode( |
8816 TokenPos(), | 8449 TokenPos(), Integer::ZoneHandle( |
8817 Integer::ZoneHandle(Z, Integer::New(TokenPos().value(), | 8450 Z, Integer::New(TokenPos().value(), Heap::kOld)))); |
8818 Heap::kOld)))); | 8451 current_block_->statements->Add(MakeStaticCall( |
8819 current_block_->statements->Add( | 8452 Symbols::FallThroughError(), |
8820 MakeStaticCall(Symbols::FallThroughError(), | 8453 Library::PrivateCoreLibName(Symbols::ThrowNew()), arguments)); |
8821 Library::PrivateCoreLibName(Symbols::ThrowNew()), | |
8822 arguments)); | |
8823 } | 8454 } |
8824 break; | 8455 break; |
8825 } | 8456 } |
8826 // The next statement still belongs to this case. | 8457 // The next statement still belongs to this case. |
8827 AstNode* statement = ParseStatement(); | 8458 AstNode* statement = ParseStatement(); |
8828 if (statement != NULL) { | 8459 if (statement != NULL) { |
8829 current_block_->statements->Add(statement); | 8460 current_block_->statements->Add(statement); |
8830 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8461 abrupt_completing_seen |= IsAbruptCompleting(statement); |
8831 } | 8462 } |
8832 } | 8463 } |
8833 SequenceNode* statements = CloseBlock(); | 8464 SequenceNode* statements = CloseBlock(); |
8834 return new(Z) CaseNode(case_pos, case_label, | 8465 return new (Z) CaseNode(case_pos, case_label, case_expressions, default_seen, |
8835 case_expressions, default_seen, switch_expr_value, statements); | 8466 switch_expr_value, statements); |
8836 } | 8467 } |
8837 | 8468 |
8838 | 8469 |
8839 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 8470 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
8840 TRACE_PARSER("ParseSwitchStatement"); | 8471 TRACE_PARSER("ParseSwitchStatement"); |
8841 ASSERT(CurrentToken() == Token::kSWITCH); | 8472 ASSERT(CurrentToken() == Token::kSWITCH); |
8842 const TokenPosition switch_pos = TokenPos(); | 8473 const TokenPosition switch_pos = TokenPos(); |
8843 SourceLabel* label = | 8474 SourceLabel* label = |
8844 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 8475 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
8845 ConsumeToken(); | 8476 ConsumeToken(); |
8846 ExpectToken(Token::kLPAREN); | 8477 ExpectToken(Token::kLPAREN); |
8847 const TokenPosition expr_pos = TokenPos(); | 8478 const TokenPosition expr_pos = TokenPos(); |
8848 AstNode* switch_expr = ParseAwaitableExpr( | 8479 AstNode* switch_expr = |
8849 kAllowConst, kConsumeCascades, NULL); | 8480 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8850 ExpectToken(Token::kRPAREN); | 8481 ExpectToken(Token::kRPAREN); |
8851 ExpectToken(Token::kLBRACE); | 8482 ExpectToken(Token::kLBRACE); |
8852 OpenBlock(); | 8483 OpenBlock(); |
8853 current_block_->scope->AddLabel(label); | 8484 current_block_->scope->AddLabel(label); |
8854 | 8485 |
8855 // Store switch expression in temporary local variable. The type of the | 8486 // Store switch expression in temporary local variable. The type of the |
8856 // variable is set to dynamic. It will later be patched to match the | 8487 // variable is set to dynamic. It will later be patched to match the |
8857 // type of the case clause expressions. Therefore, we have to allocate | 8488 // type of the case clause expressions. Therefore, we have to allocate |
8858 // a new type representing dynamic and can't reuse the canonical | 8489 // a new type representing dynamic and can't reuse the canonical |
8859 // type object for dynamic. | 8490 // type object for dynamic. |
8860 const Type& temp_var_type = Type::ZoneHandle(Z, | 8491 const Type& temp_var_type = |
8861 Type::New(Class::Handle(Z, Object::dynamic_class()), | 8492 Type::ZoneHandle(Z, Type::New(Class::Handle(Z, Object::dynamic_class()), |
8862 TypeArguments::Handle(Z), | 8493 TypeArguments::Handle(Z), expr_pos)); |
8863 expr_pos)); | |
8864 temp_var_type.SetIsFinalized(); | 8494 temp_var_type.SetIsFinalized(); |
8865 LocalVariable* temp_variable = new(Z) LocalVariable( | 8495 LocalVariable* temp_variable = new (Z) |
8866 expr_pos, expr_pos, Symbols::SwitchExpr(), temp_var_type); | 8496 LocalVariable(expr_pos, expr_pos, Symbols::SwitchExpr(), temp_var_type); |
8867 current_block_->scope->AddVariable(temp_variable); | 8497 current_block_->scope->AddVariable(temp_variable); |
8868 AstNode* save_switch_expr = new(Z) StoreLocalNode( | 8498 AstNode* save_switch_expr = |
8869 expr_pos, temp_variable, switch_expr); | 8499 new (Z) StoreLocalNode(expr_pos, temp_variable, switch_expr); |
8870 current_block_->statements->Add(save_switch_expr); | 8500 current_block_->statements->Add(save_switch_expr); |
8871 | 8501 |
8872 // Parse case clauses | 8502 // Parse case clauses |
8873 bool default_seen = false; | 8503 bool default_seen = false; |
8874 GrowableArray<LiteralNode*> case_expr_values; | 8504 GrowableArray<LiteralNode*> case_expr_values; |
8875 while (true) { | 8505 while (true) { |
8876 // Check for statement label | 8506 // Check for statement label |
8877 SourceLabel* case_label = NULL; | 8507 SourceLabel* case_label = NULL; |
8878 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 8508 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
8879 // Case statements start with a label. | 8509 // Case statements start with a label. |
8880 String* label_name = CurrentLiteral(); | 8510 String* label_name = CurrentLiteral(); |
8881 const TokenPosition label_pos = TokenPos(); | 8511 const TokenPosition label_pos = TokenPos(); |
8882 ConsumeToken(); // Consume label identifier. | 8512 ConsumeToken(); // Consume label identifier. |
8883 ConsumeToken(); // Consume colon. | 8513 ConsumeToken(); // Consume colon. |
8884 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 8514 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
8885 if (case_label == NULL) { | 8515 if (case_label == NULL) { |
8886 // Label does not exist yet. Add it to scope of switch statement. | 8516 // Label does not exist yet. Add it to scope of switch statement. |
8887 case_label = new(Z) SourceLabel( | 8517 case_label = |
8888 label_pos, *label_name, SourceLabel::kCase); | 8518 new (Z) SourceLabel(label_pos, *label_name, SourceLabel::kCase); |
8889 current_block_->scope->AddLabel(case_label); | 8519 current_block_->scope->AddLabel(case_label); |
8890 } else if (case_label->kind() == SourceLabel::kForward) { | 8520 } else if (case_label->kind() == SourceLabel::kForward) { |
8891 // We have seen a 'continue' with this label name. Resolve | 8521 // We have seen a 'continue' with this label name. Resolve |
8892 // the forward reference. | 8522 // the forward reference. |
8893 case_label->ResolveForwardReference(); | 8523 case_label->ResolveForwardReference(); |
8894 RemoveNodesForFinallyInlining(case_label); | 8524 RemoveNodesForFinallyInlining(case_label); |
8895 } else { | 8525 } else { |
8896 ReportError(label_pos, "label '%s' already exists in scope", | 8526 ReportError(label_pos, "label '%s' already exists in scope", |
8897 label_name->ToCString()); | 8527 label_name->ToCString()); |
8898 } | 8528 } |
8899 ASSERT(case_label->kind() == SourceLabel::kCase); | 8529 ASSERT(case_label->kind() == SourceLabel::kCase); |
8900 } | 8530 } |
8901 if (CurrentToken() == Token::kCASE || | 8531 if (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
8902 CurrentToken() == Token::kDEFAULT) { | |
8903 if (default_seen) { | 8532 if (default_seen) { |
8904 ReportError("no case clauses allowed after default clause"); | 8533 ReportError("no case clauses allowed after default clause"); |
8905 } | 8534 } |
8906 CaseNode* case_clause = | 8535 CaseNode* case_clause = |
8907 ParseCaseClause(temp_variable, &case_expr_values, case_label); | 8536 ParseCaseClause(temp_variable, &case_expr_values, case_label); |
8908 default_seen = case_clause->contains_default(); | 8537 default_seen = case_clause->contains_default(); |
8909 current_block_->statements->Add(case_clause); | 8538 current_block_->statements->Add(case_clause); |
8910 } else if (CurrentToken() != Token::kRBRACE) { | 8539 } else if (CurrentToken() != Token::kRBRACE) { |
8911 ReportError("'case' or '}' expected"); | 8540 ReportError("'case' or '}' expected"); |
8912 } else if (case_label != NULL) { | 8541 } else if (case_label != NULL) { |
(...skipping 13 matching lines...) Expand all Loading... |
8926 // Check for unresolved label references. | 8555 // Check for unresolved label references. |
8927 SourceLabel* unresolved_label = | 8556 SourceLabel* unresolved_label = |
8928 current_block_->scope->CheckUnresolvedLabels(); | 8557 current_block_->scope->CheckUnresolvedLabels(); |
8929 if (unresolved_label != NULL) { | 8558 if (unresolved_label != NULL) { |
8930 ReportError("unresolved reference to label '%s'", | 8559 ReportError("unresolved reference to label '%s'", |
8931 unresolved_label->name().ToCString()); | 8560 unresolved_label->name().ToCString()); |
8932 } | 8561 } |
8933 | 8562 |
8934 SequenceNode* switch_body = CloseBlock(); | 8563 SequenceNode* switch_body = CloseBlock(); |
8935 ExpectToken(Token::kRBRACE); | 8564 ExpectToken(Token::kRBRACE); |
8936 return new(Z) SwitchNode(switch_pos, label, switch_body); | 8565 return new (Z) SwitchNode(switch_pos, label, switch_body); |
8937 } | 8566 } |
8938 | 8567 |
8939 | 8568 |
8940 AstNode* Parser::ParseWhileStatement(String* label_name) { | 8569 AstNode* Parser::ParseWhileStatement(String* label_name) { |
8941 TRACE_PARSER("ParseWhileStatement"); | 8570 TRACE_PARSER("ParseWhileStatement"); |
8942 const TokenPosition while_pos = TokenPos(); | 8571 const TokenPosition while_pos = TokenPos(); |
8943 SourceLabel* label = | 8572 SourceLabel* label = |
8944 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 8573 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
8945 ConsumeToken(); | 8574 ConsumeToken(); |
8946 ExpectToken(Token::kLPAREN); | 8575 ExpectToken(Token::kLPAREN); |
8947 SequenceNode* await_preamble = NULL; | 8576 SequenceNode* await_preamble = NULL; |
8948 AstNode* cond_expr = ParseAwaitableExpr( | 8577 AstNode* cond_expr = |
8949 kAllowConst, kConsumeCascades, &await_preamble); | 8578 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
8950 ExpectToken(Token::kRPAREN); | 8579 ExpectToken(Token::kRPAREN); |
8951 const bool parsing_loop_body = true; | 8580 const bool parsing_loop_body = true; |
8952 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 8581 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
8953 WhileNode* while_node = new (Z) WhileNode(while_pos, | 8582 WhileNode* while_node = new (Z) |
8954 label, | 8583 WhileNode(while_pos, label, cond_expr, await_preamble, while_body); |
8955 cond_expr, | |
8956 await_preamble, | |
8957 while_body); | |
8958 return while_node; | 8584 return while_node; |
8959 } | 8585 } |
8960 | 8586 |
8961 | 8587 |
8962 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 8588 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
8963 TRACE_PARSER("ParseDoWhileStatement"); | 8589 TRACE_PARSER("ParseDoWhileStatement"); |
8964 const TokenPosition do_pos = TokenPos(); | 8590 const TokenPosition do_pos = TokenPos(); |
8965 SourceLabel* label = | 8591 SourceLabel* label = |
8966 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 8592 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
8967 ConsumeToken(); | 8593 ConsumeToken(); |
8968 const bool parsing_loop_body = true; | 8594 const bool parsing_loop_body = true; |
8969 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 8595 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
8970 ExpectToken(Token::kWHILE); | 8596 ExpectToken(Token::kWHILE); |
8971 ExpectToken(Token::kLPAREN); | 8597 ExpectToken(Token::kLPAREN); |
8972 SequenceNode* await_preamble = NULL; | 8598 SequenceNode* await_preamble = NULL; |
8973 TokenPosition expr_pos = TokenPos(); | 8599 TokenPosition expr_pos = TokenPos(); |
8974 AstNode* cond_expr = | 8600 AstNode* cond_expr = |
8975 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8601 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
8976 if (await_preamble != NULL) { | 8602 if (await_preamble != NULL) { |
8977 // Prepend the preamble to the condition. | 8603 // Prepend the preamble to the condition. |
8978 LetNode* await_cond = new(Z) LetNode(expr_pos); | 8604 LetNode* await_cond = new (Z) LetNode(expr_pos); |
8979 await_cond->AddNode(await_preamble); | 8605 await_cond->AddNode(await_preamble); |
8980 await_cond->AddNode(cond_expr); | 8606 await_cond->AddNode(cond_expr); |
8981 cond_expr = await_cond; | 8607 cond_expr = await_cond; |
8982 } | 8608 } |
8983 ExpectToken(Token::kRPAREN); | 8609 ExpectToken(Token::kRPAREN); |
8984 ExpectSemicolon(); | 8610 ExpectSemicolon(); |
8985 return new(Z) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 8611 return new (Z) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
8986 } | 8612 } |
8987 | 8613 |
8988 | 8614 |
8989 static LocalVariable* LookupSavedTryContextVar(LocalScope* scope) { | 8615 static LocalVariable* LookupSavedTryContextVar(LocalScope* scope) { |
8990 LocalVariable* var = | 8616 LocalVariable* var = |
8991 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 8617 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
8992 ASSERT((var != NULL) && !var->is_captured()); | 8618 ASSERT((var != NULL) && !var->is_captured()); |
8993 return var; | 8619 return var; |
8994 } | 8620 } |
8995 | 8621 |
8996 | 8622 |
8997 static LocalVariable* LookupAsyncSavedTryContextVar(Thread* thread, | 8623 static LocalVariable* LookupAsyncSavedTryContextVar(Thread* thread, |
8998 LocalScope* scope, | 8624 LocalScope* scope, |
8999 uint16_t try_index) { | 8625 uint16_t try_index) { |
9000 Zone* zone = thread->zone(); | 8626 Zone* zone = thread->zone(); |
9001 const String& async_saved_try_ctx_name = String::ZoneHandle(zone, | 8627 const String& async_saved_try_ctx_name = String::ZoneHandle( |
9002 Symbols::NewFormatted(thread, | 8628 zone, Symbols::NewFormatted( |
9003 "%s%d", | 8629 thread, "%s%d", |
9004 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 8630 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), try_index)); |
9005 try_index)); | |
9006 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); | 8631 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); |
9007 ASSERT(var != NULL); | 8632 ASSERT(var != NULL); |
9008 return var; | 8633 return var; |
9009 } | 8634 } |
9010 | 8635 |
9011 | 8636 |
9012 // If the await or yield being parsed is in a try block, the continuation code | 8637 // If the await or yield being parsed is in a try block, the continuation code |
9013 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, | 8638 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, |
9014 // and the stack-based variable :saved_try_ctx_var of the outer try block. | 8639 // and the stack-based variable :saved_try_ctx_var of the outer try block. |
9015 // The inner :saved_try_ctx_var is used by a finally clause handling an | 8640 // The inner :saved_try_ctx_var is used by a finally clause handling an |
(...skipping 17 matching lines...) Expand all Loading... |
9033 *outer_saved_try_ctx = NULL; | 8658 *outer_saved_try_ctx = NULL; |
9034 *outer_async_saved_try_ctx = NULL; | 8659 *outer_async_saved_try_ctx = NULL; |
9035 if (try_stack_ != NULL) { | 8660 if (try_stack_ != NULL) { |
9036 LocalScope* scope = try_stack_->try_block()->scope; | 8661 LocalScope* scope = try_stack_->try_block()->scope; |
9037 uint16_t try_index = try_stack_->try_index(); | 8662 uint16_t try_index = try_stack_->try_index(); |
9038 const int current_function_level = FunctionLevel(); | 8663 const int current_function_level = FunctionLevel(); |
9039 if (scope->function_level() == current_function_level) { | 8664 if (scope->function_level() == current_function_level) { |
9040 // The block declaring :saved_try_ctx_var variable is the parent of the | 8665 // The block declaring :saved_try_ctx_var variable is the parent of the |
9041 // pushed try block. | 8666 // pushed try block. |
9042 *saved_try_ctx = LookupSavedTryContextVar(scope->parent()); | 8667 *saved_try_ctx = LookupSavedTryContextVar(scope->parent()); |
9043 *async_saved_try_ctx = LookupAsyncSavedTryContextVar(T, | 8668 *async_saved_try_ctx = |
9044 async_temp_scope_, try_index); | 8669 LookupAsyncSavedTryContextVar(T, async_temp_scope_, try_index); |
9045 if ((try_stack_->outer_try() != NULL) && !try_stack_->inside_finally()) { | 8670 if ((try_stack_->outer_try() != NULL) && !try_stack_->inside_finally()) { |
9046 // Collecting the outer try scope is not necessary if we | 8671 // Collecting the outer try scope is not necessary if we |
9047 // are in a finally block. | 8672 // are in a finally block. |
9048 scope = try_stack_->outer_try()->try_block()->scope; | 8673 scope = try_stack_->outer_try()->try_block()->scope; |
9049 try_index = try_stack_->outer_try()->try_index(); | 8674 try_index = try_stack_->outer_try()->try_index(); |
9050 if (scope->function_level() == current_function_level) { | 8675 if (scope->function_level() == current_function_level) { |
9051 *outer_saved_try_ctx = LookupSavedTryContextVar(scope->parent()); | 8676 *outer_saved_try_ctx = LookupSavedTryContextVar(scope->parent()); |
9052 *outer_async_saved_try_ctx = LookupAsyncSavedTryContextVar(T, | 8677 *outer_async_saved_try_ctx = |
9053 async_temp_scope_, try_index); | 8678 LookupAsyncSavedTryContextVar(T, async_temp_scope_, try_index); |
9054 } | 8679 } |
9055 } | 8680 } |
9056 } | 8681 } |
9057 } | 8682 } |
9058 // An async or async* has an implicitly created try-catch around the | 8683 // An async or async* has an implicitly created try-catch around the |
9059 // function body, so the await or yield inside the async closure should always | 8684 // function body, so the await or yield inside the async closure should always |
9060 // be created with a try scope. | 8685 // be created with a try scope. |
9061 ASSERT((*saved_try_ctx != NULL) || | 8686 ASSERT((*saved_try_ctx != NULL) || innermost_function().IsAsyncFunction() || |
9062 innermost_function().IsAsyncFunction() || | |
9063 innermost_function().IsAsyncGenerator() || | 8687 innermost_function().IsAsyncGenerator() || |
9064 innermost_function().IsSyncGenClosure() || | 8688 innermost_function().IsSyncGenClosure() || |
9065 innermost_function().IsSyncGenerator()); | 8689 innermost_function().IsSyncGenerator()); |
9066 } | 8690 } |
9067 | 8691 |
9068 | 8692 |
9069 // Build an AST node for static call to Dart function print(str). | 8693 // Build an AST node for static call to Dart function print(str). |
9070 // Used during debugging to insert print in generated dart code. | 8694 // Used during debugging to insert print in generated dart code. |
9071 AstNode* Parser::DartPrint(const char* str) { | 8695 AstNode* Parser::DartPrint(const char* str) { |
9072 const Library& lib = Library::Handle(Library::CoreLibrary()); | 8696 const Library& lib = Library::Handle(Library::CoreLibrary()); |
9073 const Function& print_fn = Function::ZoneHandle( | 8697 const Function& print_fn = |
9074 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 8698 Function::ZoneHandle(Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
9075 ASSERT(!print_fn.IsNull()); | 8699 ASSERT(!print_fn.IsNull()); |
9076 ArgumentListNode* one_arg = | 8700 ArgumentListNode* one_arg = |
9077 new(Z) ArgumentListNode(TokenPosition::kNoSource); | 8701 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
9078 String& msg = String::ZoneHandle(Symbols::NewFormatted(T, "%s", str)); | 8702 String& msg = String::ZoneHandle(Symbols::NewFormatted(T, "%s", str)); |
9079 one_arg->Add(new(Z) LiteralNode(TokenPosition::kNoSource, msg)); | 8703 one_arg->Add(new (Z) LiteralNode(TokenPosition::kNoSource, msg)); |
9080 AstNode* print_call = | 8704 AstNode* print_call = |
9081 new(Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg); | 8705 new (Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg); |
9082 return print_call; | 8706 return print_call; |
9083 } | 8707 } |
9084 | 8708 |
9085 | 8709 |
9086 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 8710 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
9087 TRACE_PARSER("ParseAwaitForStatement"); | 8711 TRACE_PARSER("ParseAwaitForStatement"); |
9088 ASSERT(IsAwaitKeyword()); | 8712 ASSERT(IsAwaitKeyword()); |
9089 const TokenPosition await_for_pos = TokenPos(); | 8713 const TokenPosition await_for_pos = TokenPos(); |
9090 ConsumeToken(); // await. | 8714 ConsumeToken(); // await. |
9091 ASSERT(CurrentToken() == Token::kFOR); | 8715 ASSERT(CurrentToken() == Token::kFOR); |
9092 ConsumeToken(); // for. | 8716 ConsumeToken(); // for. |
9093 ExpectToken(Token::kLPAREN); | 8717 ExpectToken(Token::kLPAREN); |
9094 | 8718 |
9095 if (!innermost_function().IsAsyncFunction() && | 8719 if (!innermost_function().IsAsyncFunction() && |
9096 !innermost_function().IsAsyncClosure() && | 8720 !innermost_function().IsAsyncClosure() && |
9097 !innermost_function().IsAsyncGenerator() && | 8721 !innermost_function().IsAsyncGenerator() && |
9098 !innermost_function().IsAsyncGenClosure()) { | 8722 !innermost_function().IsAsyncGenClosure()) { |
9099 ReportError(await_for_pos, | 8723 ReportError(await_for_pos, |
9100 "await for loop is only allowed in an asynchronous function"); | 8724 "await for loop is only allowed in an asynchronous function"); |
9101 } | 8725 } |
9102 | 8726 |
9103 // Parse loop variable. | 8727 // Parse loop variable. |
9104 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8728 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
9105 if (CurrentToken() == Token::kCONST) { | 8729 if (CurrentToken() == Token::kCONST) { |
9106 ReportError("Loop variable cannot be 'const'"); | 8730 ReportError("Loop variable cannot be 'const'"); |
9107 } | 8731 } |
9108 bool new_loop_var = false; | 8732 bool new_loop_var = false; |
9109 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8733 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
9110 if (LookaheadToken(1) != Token::kIN) { | 8734 if (LookaheadToken(1) != Token::kIN) { |
9111 // Declaration of a new loop variable. | 8735 // Declaration of a new loop variable. |
9112 // Delay creation of the local variable until we know its actual | 8736 // Delay creation of the local variable until we know its actual |
9113 // position, which is inside the loop body. | 8737 // position, which is inside the loop body. |
9114 new_loop_var = true; | 8738 new_loop_var = true; |
9115 loop_var_type = ParseConstFinalVarOrType( | 8739 loop_var_type = ParseConstFinalVarOrType(I->type_checks() |
9116 I->type_checks() ? ClassFinalizer::kCanonicalize : | 8740 ? ClassFinalizer::kCanonicalize |
9117 ClassFinalizer::kIgnore); | 8741 : ClassFinalizer::kIgnore); |
9118 } | 8742 } |
9119 TokenPosition loop_var_pos = TokenPos(); | 8743 TokenPosition loop_var_pos = TokenPos(); |
9120 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 8744 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
9121 | 8745 |
9122 // Parse stream expression. | 8746 // Parse stream expression. |
9123 ExpectToken(Token::kIN); | 8747 ExpectToken(Token::kIN); |
9124 | 8748 |
9125 // Open a block for the iterator variable and the try-finally statement | 8749 // Open a block for the iterator variable and the try-finally statement |
9126 // that contains the loop. Ensure that the block starts at a different | 8750 // that contains the loop. Ensure that the block starts at a different |
9127 // token position than the following loop block. Both blocks can allocate | 8751 // token position than the following loop block. Both blocks can allocate |
9128 // contexts and if they have a matching token position range, | 8752 // contexts and if they have a matching token position range, |
9129 // it can be an issue (cf. bug 26941). | 8753 // it can be an issue (cf. bug 26941). |
9130 OpenBlock(); | 8754 OpenBlock(); |
9131 const Block* await_for_block = current_block_; | 8755 const Block* await_for_block = current_block_; |
9132 | 8756 |
9133 const TokenPosition stream_expr_pos = TokenPos(); | 8757 const TokenPosition stream_expr_pos = TokenPos(); |
9134 AstNode* stream_expr = | 8758 AstNode* stream_expr = |
9135 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8759 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9136 ExpectToken(Token::kRPAREN); | 8760 ExpectToken(Token::kRPAREN); |
9137 | 8761 |
9138 // Build creation of implicit StreamIterator. | 8762 // Build creation of implicit StreamIterator. |
9139 // var :for-in-iter = new StreamIterator(stream_expr). | 8763 // var :for-in-iter = new StreamIterator(stream_expr). |
9140 const Class& stream_iterator_cls = | 8764 const Class& stream_iterator_cls = |
9141 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); | 8765 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); |
9142 ASSERT(!stream_iterator_cls.IsNull()); | 8766 ASSERT(!stream_iterator_cls.IsNull()); |
9143 const Function& iterator_ctor = | 8767 const Function& iterator_ctor = Function::ZoneHandle( |
9144 Function::ZoneHandle(Z, stream_iterator_cls.LookupFunction( | 8768 Z, |
9145 Symbols::StreamIteratorConstructor())); | 8769 stream_iterator_cls.LookupFunction(Symbols::StreamIteratorConstructor())); |
9146 ASSERT(!iterator_ctor.IsNull()); | 8770 ASSERT(!iterator_ctor.IsNull()); |
9147 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos); | 8771 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos); |
9148 ctor_args->Add(stream_expr); | 8772 ctor_args->Add(stream_expr); |
9149 ConstructorCallNode* ctor_call = | 8773 ConstructorCallNode* ctor_call = new (Z) ConstructorCallNode( |
9150 new (Z) ConstructorCallNode(stream_expr_pos, | 8774 stream_expr_pos, TypeArguments::ZoneHandle(Z), iterator_ctor, ctor_args); |
9151 TypeArguments::ZoneHandle(Z), | |
9152 iterator_ctor, | |
9153 ctor_args); | |
9154 const AbstractType& iterator_type = Object::dynamic_type(); | 8775 const AbstractType& iterator_type = Object::dynamic_type(); |
9155 LocalVariable* iterator_var = new(Z) LocalVariable( | 8776 LocalVariable* iterator_var = new (Z) LocalVariable( |
9156 stream_expr_pos, stream_expr_pos, Symbols::ForInIter(), iterator_type); | 8777 stream_expr_pos, stream_expr_pos, Symbols::ForInIter(), iterator_type); |
9157 current_block_->scope->AddVariable(iterator_var); | 8778 current_block_->scope->AddVariable(iterator_var); |
9158 AstNode* iterator_init = | 8779 AstNode* iterator_init = |
9159 new(Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call); | 8780 new (Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call); |
9160 current_block_->statements->Add(iterator_init); | 8781 current_block_->statements->Add(iterator_init); |
9161 | 8782 |
9162 // We need to ensure that the stream is cancelled after the loop. | 8783 // We need to ensure that the stream is cancelled after the loop. |
9163 // Thus, wrap the loop in a try-finally that calls :for-in-iter.close() | 8784 // Thus, wrap the loop in a try-finally that calls :for-in-iter.close() |
9164 // in the finally clause. It is harmless to call close() if the stream | 8785 // in the finally clause. It is harmless to call close() if the stream |
9165 // is already cancelled (when moveNext() returns false). | 8786 // is already cancelled (when moveNext() returns false). |
9166 // Note: even though this is async code, we do not need to set up | 8787 // Note: even though this is async code, we do not need to set up |
9167 // the closurized saved_exception_var and saved_stack_trace_var because | 8788 // the closurized saved_exception_var and saved_stack_trace_var because |
9168 // there can not be a suspend/resume event before the exception is | 8789 // there can not be a suspend/resume event before the exception is |
9169 // rethrown in the catch clause. The catch block of the implicit | 8790 // rethrown in the catch clause. The catch block of the implicit |
9170 // try-finally is empty. | 8791 // try-finally is empty. |
9171 LocalVariable* context_var = NULL; | 8792 LocalVariable* context_var = NULL; |
9172 LocalVariable* exception_var = NULL; | 8793 LocalVariable* exception_var = NULL; |
9173 LocalVariable* stack_trace_var = NULL; | 8794 LocalVariable* stack_trace_var = NULL; |
9174 LocalVariable* saved_exception_var = NULL; | 8795 LocalVariable* saved_exception_var = NULL; |
9175 LocalVariable* saved_stack_trace_var = NULL; | 8796 LocalVariable* saved_stack_trace_var = NULL; |
9176 SetupExceptionVariables(current_block_->scope, | 8797 SetupExceptionVariables(current_block_->scope, |
9177 false, // Do not create the saved_ vars. | 8798 false, // Do not create the saved_ vars. |
9178 &context_var, | 8799 &context_var, &exception_var, &stack_trace_var, |
9179 &exception_var, | 8800 &saved_exception_var, &saved_stack_trace_var); |
9180 &stack_trace_var, | |
9181 &saved_exception_var, | |
9182 &saved_stack_trace_var); | |
9183 OpenBlock(); // try block. | 8801 OpenBlock(); // try block. |
9184 PushTry(current_block_); | 8802 PushTry(current_block_); |
9185 SetupSavedTryContext(context_var); | 8803 SetupSavedTryContext(context_var); |
9186 | 8804 |
9187 // Build while loop condition. | 8805 // Build while loop condition. |
9188 // while (await :for-in-iter.moveNext()) | 8806 // while (await :for-in-iter.moveNext()) |
9189 LocalVariable* saved_try_ctx; | 8807 LocalVariable* saved_try_ctx; |
9190 LocalVariable* async_saved_try_ctx; | 8808 LocalVariable* async_saved_try_ctx; |
9191 LocalVariable* outer_saved_try_ctx; | 8809 LocalVariable* outer_saved_try_ctx; |
9192 LocalVariable* outer_async_saved_try_ctx; | 8810 LocalVariable* outer_async_saved_try_ctx; |
9193 CheckAsyncOpInTryBlock(&saved_try_ctx, | 8811 CheckAsyncOpInTryBlock(&saved_try_ctx, &async_saved_try_ctx, |
9194 &async_saved_try_ctx, | 8812 &outer_saved_try_ctx, &outer_async_saved_try_ctx); |
9195 &outer_saved_try_ctx, | 8813 ArgumentListNode* no_args = new (Z) ArgumentListNode(stream_expr_pos); |
9196 &outer_async_saved_try_ctx); | 8814 AstNode* iterator_moveNext = new (Z) InstanceCallNode( |
9197 ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_expr_pos); | 8815 stream_expr_pos, new (Z) LoadLocalNode(stream_expr_pos, iterator_var), |
9198 AstNode* iterator_moveNext = new(Z) InstanceCallNode( | 8816 Symbols::MoveNext(), no_args); |
9199 stream_expr_pos, | |
9200 new(Z) LoadLocalNode(stream_expr_pos, iterator_var), | |
9201 Symbols::MoveNext(), | |
9202 no_args); | |
9203 OpenBlock(); | 8817 OpenBlock(); |
9204 AstNode* await_moveNext = | 8818 AstNode* await_moveNext = new (Z) AwaitNode( |
9205 new(Z) AwaitNode(stream_expr_pos, | 8819 stream_expr_pos, iterator_moveNext, saved_try_ctx, async_saved_try_ctx, |
9206 iterator_moveNext, | 8820 outer_saved_try_ctx, outer_async_saved_try_ctx, current_block_->scope); |
9207 saved_try_ctx, | |
9208 async_saved_try_ctx, | |
9209 outer_saved_try_ctx, | |
9210 outer_async_saved_try_ctx, | |
9211 current_block_->scope); | |
9212 AwaitTransformer at(current_block_->statements, async_temp_scope_); | 8821 AwaitTransformer at(current_block_->statements, async_temp_scope_); |
9213 await_moveNext = at.Transform(await_moveNext); | 8822 await_moveNext = at.Transform(await_moveNext); |
9214 SequenceNode* await_preamble = CloseBlock(); | 8823 SequenceNode* await_preamble = CloseBlock(); |
9215 | 8824 |
9216 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 8825 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
9217 // here, but that does not work well because we have to insert an implicit | 8826 // here, but that does not work well because we have to insert an implicit |
9218 // variable assignment and potentially a variable declaration in the | 8827 // variable assignment and potentially a variable declaration in the |
9219 // loop body. | 8828 // loop body. |
9220 OpenLoopBlock(); | 8829 OpenLoopBlock(); |
9221 | 8830 |
9222 SourceLabel* label = | 8831 SourceLabel* label = |
9223 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); | 8832 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); |
9224 current_block_->scope->AddLabel(label); | 8833 current_block_->scope->AddLabel(label); |
9225 const TokenPosition loop_var_assignment_pos = TokenPos(); | 8834 const TokenPosition loop_var_assignment_pos = TokenPos(); |
9226 | 8835 |
9227 AstNode* iterator_current = new(Z) InstanceGetterNode( | 8836 AstNode* iterator_current = new (Z) InstanceGetterNode( |
9228 loop_var_assignment_pos, | 8837 loop_var_assignment_pos, |
9229 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 8838 new (Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
9230 Symbols::Current()); | 8839 Symbols::Current()); |
9231 | 8840 |
9232 // Generate assignment of next iterator value to loop variable. | 8841 // Generate assignment of next iterator value to loop variable. |
9233 AstNode* loop_var_assignment = NULL; | 8842 AstNode* loop_var_assignment = NULL; |
9234 if (new_loop_var) { | 8843 if (new_loop_var) { |
9235 // The for loop variable is new for each iteration. | 8844 // The for loop variable is new for each iteration. |
9236 // Create a variable and add it to the loop body scope. | 8845 // Create a variable and add it to the loop body scope. |
9237 // Note that the variable token position needs to be inside the | 8846 // Note that the variable token position needs to be inside the |
9238 // loop block, so it gets put in the loop context level. | 8847 // loop block, so it gets put in the loop context level. |
9239 LocalVariable* loop_var = | 8848 LocalVariable* loop_var = |
9240 new(Z) LocalVariable(loop_var_assignment_pos, | 8849 new (Z) LocalVariable(loop_var_assignment_pos, loop_var_assignment_pos, |
9241 loop_var_assignment_pos, | 8850 *loop_var_name, loop_var_type); |
9242 *loop_var_name, | |
9243 loop_var_type); | |
9244 if (loop_var_is_final) { | 8851 if (loop_var_is_final) { |
9245 loop_var->set_is_final(); | 8852 loop_var->set_is_final(); |
9246 } | 8853 } |
9247 current_block_->scope->AddVariable(loop_var); | 8854 current_block_->scope->AddVariable(loop_var); |
9248 loop_var_assignment = new(Z) StoreLocalNode( | 8855 loop_var_assignment = new (Z) |
9249 loop_var_assignment_pos, loop_var, iterator_current); | 8856 StoreLocalNode(loop_var_assignment_pos, loop_var, iterator_current); |
9250 } else { | 8857 } else { |
9251 AstNode* loop_var_primary = | 8858 AstNode* loop_var_primary = |
9252 ResolveIdent(loop_var_pos, *loop_var_name, false); | 8859 ResolveIdent(loop_var_pos, *loop_var_name, false); |
9253 ASSERT(!loop_var_primary->IsPrimaryNode()); | 8860 ASSERT(!loop_var_primary->IsPrimaryNode()); |
9254 loop_var_assignment = CreateAssignmentNode(loop_var_primary, | 8861 loop_var_assignment = |
9255 iterator_current, | 8862 CreateAssignmentNode(loop_var_primary, iterator_current, loop_var_name, |
9256 loop_var_name, | 8863 loop_var_assignment_pos); |
9257 loop_var_assignment_pos); | |
9258 ASSERT(loop_var_assignment != NULL); | 8864 ASSERT(loop_var_assignment != NULL); |
9259 } | 8865 } |
9260 current_block_->statements->Add(loop_var_assignment); | 8866 current_block_->statements->Add(loop_var_assignment); |
9261 | 8867 |
9262 // Now parse the for-in loop statement or block. | 8868 // Now parse the for-in loop statement or block. |
9263 if (CurrentToken() == Token::kLBRACE) { | 8869 if (CurrentToken() == Token::kLBRACE) { |
9264 ConsumeToken(); | 8870 ConsumeToken(); |
9265 ParseStatementSequence(); | 8871 ParseStatementSequence(); |
9266 ExpectToken(Token::kRBRACE); | 8872 ExpectToken(Token::kRBRACE); |
9267 } else { | 8873 } else { |
9268 AstNode* statement = ParseStatement(); | 8874 AstNode* statement = ParseStatement(); |
9269 if (statement != NULL) { | 8875 if (statement != NULL) { |
9270 current_block_->statements->Add(statement); | 8876 current_block_->statements->Add(statement); |
9271 } | 8877 } |
9272 } | 8878 } |
9273 SequenceNode* for_loop_block = CloseBlock(); | 8879 SequenceNode* for_loop_block = CloseBlock(); |
9274 | 8880 |
9275 WhileNode* while_node = new (Z) WhileNode(await_for_pos, | 8881 WhileNode* while_node = new (Z) WhileNode( |
9276 label, | 8882 await_for_pos, label, await_moveNext, await_preamble, for_loop_block); |
9277 await_moveNext, | |
9278 await_preamble, | |
9279 for_loop_block); | |
9280 // Add the while loop to the try block. | 8883 // Add the while loop to the try block. |
9281 current_block_->statements->Add(while_node); | 8884 current_block_->statements->Add(while_node); |
9282 SequenceNode* try_block = CloseBlock(); | 8885 SequenceNode* try_block = CloseBlock(); |
9283 | 8886 |
9284 // Create an empty "catch all" block that rethrows the current | 8887 // Create an empty "catch all" block that rethrows the current |
9285 // exception and stacktrace. | 8888 // exception and stacktrace. |
9286 try_stack_->enter_catch(); | 8889 try_stack_->enter_catch(); |
9287 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); | 8890 SequenceNode* catch_block = new (Z) SequenceNode(await_for_pos, NULL); |
9288 | 8891 |
9289 if (outer_saved_try_ctx != NULL) { | 8892 if (outer_saved_try_ctx != NULL) { |
9290 catch_block->Add(new (Z) StoreLocalNode( | 8893 catch_block->Add(new (Z) StoreLocalNode( |
9291 TokenPosition::kNoSource, | 8894 TokenPosition::kNoSource, outer_saved_try_ctx, |
9292 outer_saved_try_ctx, | |
9293 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 8895 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9294 outer_async_saved_try_ctx))); | 8896 outer_async_saved_try_ctx))); |
9295 } | 8897 } |
9296 | 8898 |
9297 // We don't need to copy the current exception and stack trace variables | 8899 // We don't need to copy the current exception and stack trace variables |
9298 // into :saved_exception_var and :saved_stack_trace_var here because there | 8900 // into :saved_exception_var and :saved_stack_trace_var here because there |
9299 // is no code in the catch clause that could suspend the function. | 8901 // is no code in the catch clause that could suspend the function. |
9300 | 8902 |
9301 // Rethrow the exception. | 8903 // Rethrow the exception. |
9302 catch_block->Add(new(Z) ThrowNode( | 8904 catch_block->Add(new (Z) ThrowNode( |
9303 await_for_pos, | 8905 await_for_pos, new (Z) LoadLocalNode(await_for_pos, exception_var), |
9304 new(Z) LoadLocalNode(await_for_pos, exception_var), | 8906 new (Z) LoadLocalNode(await_for_pos, stack_trace_var))); |
9305 new(Z) LoadLocalNode(await_for_pos, stack_trace_var))); | |
9306 | 8907 |
9307 TryStack* try_statement = PopTry(); | 8908 TryStack* try_statement = PopTry(); |
9308 const intptr_t try_index = try_statement->try_index(); | 8909 const intptr_t try_index = try_statement->try_index(); |
9309 TryStack* outer_try = try_stack_; | 8910 TryStack* outer_try = try_stack_; |
9310 const intptr_t outer_try_index = (outer_try != NULL) ? | 8911 const intptr_t outer_try_index = (outer_try != NULL) |
9311 outer_try->try_index() : CatchClauseNode::kInvalidTryIndex; | 8912 ? outer_try->try_index() |
| 8913 : CatchClauseNode::kInvalidTryIndex; |
9312 | 8914 |
9313 // The finally block contains a call to cancel the stream. | 8915 // The finally block contains a call to cancel the stream. |
9314 // :for-in-iter.cancel(); | 8916 // :for-in-iter.cancel(); |
9315 | 8917 |
9316 // Inline the finally block to the exit points in the try block. | 8918 // Inline the finally block to the exit points in the try block. |
9317 intptr_t node_index = 0; | 8919 intptr_t node_index = 0; |
9318 SequenceNode* finally_clause = NULL; | 8920 SequenceNode* finally_clause = NULL; |
9319 if (try_stack_ != NULL) { | 8921 if (try_stack_ != NULL) { |
9320 try_stack_->enter_finally(); | 8922 try_stack_->enter_finally(); |
9321 } | 8923 } |
9322 do { | 8924 do { |
9323 OpenBlock(); | 8925 OpenBlock(); |
9324 | 8926 |
9325 // Restore the saved try context of the enclosing try block if one | 8927 // Restore the saved try context of the enclosing try block if one |
9326 // exists. | 8928 // exists. |
9327 if (outer_saved_try_ctx != NULL) { | 8929 if (outer_saved_try_ctx != NULL) { |
9328 current_block_->statements->Add(new (Z) StoreLocalNode( | 8930 current_block_->statements->Add(new (Z) StoreLocalNode( |
9329 TokenPosition::kNoSource, | 8931 TokenPosition::kNoSource, outer_saved_try_ctx, |
9330 outer_saved_try_ctx, | |
9331 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 8932 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9332 outer_async_saved_try_ctx))); | 8933 outer_async_saved_try_ctx))); |
9333 } | 8934 } |
9334 // :for-in-iter.cancel(); | 8935 // :for-in-iter.cancel(); |
9335 ArgumentListNode* no_args = | 8936 ArgumentListNode* no_args = |
9336 new(Z) ArgumentListNode(TokenPosition::kNoSource); | 8937 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
9337 current_block_->statements->Add( | 8938 current_block_->statements->Add(new (Z) InstanceCallNode( |
9338 new(Z) InstanceCallNode(TokenPosition::kNoSource, | 8939 TokenPosition::kNoSource, |
9339 new(Z) LoadLocalNode(TokenPosition::kNoSource, iterator_var), | 8940 new (Z) LoadLocalNode(TokenPosition::kNoSource, iterator_var), |
9340 Symbols::Cancel(), | 8941 Symbols::Cancel(), no_args)); |
9341 no_args)); | |
9342 finally_clause = CloseBlock(); | 8942 finally_clause = CloseBlock(); |
9343 | 8943 |
9344 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 8944 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
9345 if (node_to_inline != NULL) { | 8945 if (node_to_inline != NULL) { |
9346 InlinedFinallyNode* node = | 8946 InlinedFinallyNode* node = |
9347 new(Z) InlinedFinallyNode(TokenPosition::kNoSource, | 8947 new (Z) InlinedFinallyNode(TokenPosition::kNoSource, finally_clause, |
9348 finally_clause, | 8948 context_var, outer_try_index); |
9349 context_var, | |
9350 outer_try_index); | |
9351 finally_clause = NULL; | 8949 finally_clause = NULL; |
9352 AddFinallyClauseToNode(true, node_to_inline, node); | 8950 AddFinallyClauseToNode(true, node_to_inline, node); |
9353 node_index++; | 8951 node_index++; |
9354 } | 8952 } |
9355 } while (finally_clause == NULL); | 8953 } while (finally_clause == NULL); |
9356 | 8954 |
9357 if (try_stack_ != NULL) { | 8955 if (try_stack_ != NULL) { |
9358 try_stack_->exit_finally(); | 8956 try_stack_->exit_finally(); |
9359 } | 8957 } |
9360 | 8958 |
9361 // Create the try-statement and add to the current sequence, which is | 8959 // Create the try-statement and add to the current sequence, which is |
9362 // the block around the loop statement. | 8960 // the block around the loop statement. |
9363 | 8961 |
9364 const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); | 8962 const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); |
9365 // Catch block handles all exceptions. | 8963 // Catch block handles all exceptions. |
9366 handler_types.SetAt(0, Object::dynamic_type()); | 8964 handler_types.SetAt(0, Object::dynamic_type()); |
9367 | 8965 |
9368 CatchClauseNode* catch_clause = new(Z) CatchClauseNode(await_for_pos, | 8966 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
9369 catch_block, | 8967 await_for_pos, catch_block, handler_types, context_var, exception_var, |
9370 handler_types, | 8968 stack_trace_var, exception_var, stack_trace_var, AllocateTryIndex(), |
9371 context_var, | |
9372 exception_var, | |
9373 stack_trace_var, | |
9374 exception_var, | |
9375 stack_trace_var, | |
9376 AllocateTryIndex(), | |
9377 true); // Needs stack trace. | 8969 true); // Needs stack trace. |
9378 | 8970 |
9379 AstNode* try_catch_node = | 8971 AstNode* try_catch_node = |
9380 new(Z) TryCatchNode(await_for_pos, | 8972 new (Z) TryCatchNode(await_for_pos, try_block, context_var, catch_clause, |
9381 try_block, | 8973 finally_clause, try_index, finally_clause); |
9382 context_var, | |
9383 catch_clause, | |
9384 finally_clause, | |
9385 try_index, | |
9386 finally_clause); | |
9387 | 8974 |
9388 ASSERT(current_block_ == await_for_block); | 8975 ASSERT(current_block_ == await_for_block); |
9389 await_for_block->statements->Add(try_catch_node); | 8976 await_for_block->statements->Add(try_catch_node); |
9390 | 8977 |
9391 return CloseBlock(); // Implicit block around while loop. | 8978 return CloseBlock(); // Implicit block around while loop. |
9392 } | 8979 } |
9393 | 8980 |
9394 | 8981 |
9395 AstNode* Parser::ParseForInStatement(TokenPosition forin_pos, | 8982 AstNode* Parser::ParseForInStatement(TokenPosition forin_pos, |
9396 SourceLabel* label) { | 8983 SourceLabel* label) { |
9397 TRACE_PARSER("ParseForInStatement"); | 8984 TRACE_PARSER("ParseForInStatement"); |
9398 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8985 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
9399 if (CurrentToken() == Token::kCONST) { | 8986 if (CurrentToken() == Token::kCONST) { |
9400 ReportError("Loop variable cannot be 'const'"); | 8987 ReportError("Loop variable cannot be 'const'"); |
9401 } | 8988 } |
9402 const String* loop_var_name = NULL; | 8989 const String* loop_var_name = NULL; |
9403 TokenPosition loop_var_pos = TokenPosition::kNoSource; | 8990 TokenPosition loop_var_pos = TokenPosition::kNoSource; |
9404 bool new_loop_var = false; | 8991 bool new_loop_var = false; |
9405 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8992 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
9406 if (LookaheadToken(1) == Token::kIN) { | 8993 if (LookaheadToken(1) == Token::kIN) { |
9407 loop_var_pos = TokenPos(); | 8994 loop_var_pos = TokenPos(); |
9408 loop_var_name = ExpectIdentifier("variable name expected"); | 8995 loop_var_name = ExpectIdentifier("variable name expected"); |
9409 } else { | 8996 } else { |
9410 // The case without a type is handled above, so require a type here. | 8997 // The case without a type is handled above, so require a type here. |
9411 // Delay creation of the local variable until we know its actual | 8998 // Delay creation of the local variable until we know its actual |
9412 // position, which is inside the loop body. | 8999 // position, which is inside the loop body. |
9413 new_loop_var = true; | 9000 new_loop_var = true; |
9414 loop_var_type = ParseConstFinalVarOrType( | 9001 loop_var_type = ParseConstFinalVarOrType(I->type_checks() |
9415 I->type_checks() ? ClassFinalizer::kCanonicalize : | 9002 ? ClassFinalizer::kCanonicalize |
9416 ClassFinalizer::kIgnore); | 9003 : ClassFinalizer::kIgnore); |
9417 loop_var_pos = TokenPos(); | 9004 loop_var_pos = TokenPos(); |
9418 loop_var_name = ExpectIdentifier("variable name expected"); | 9005 loop_var_name = ExpectIdentifier("variable name expected"); |
9419 } | 9006 } |
9420 ExpectToken(Token::kIN); | 9007 ExpectToken(Token::kIN); |
9421 | 9008 |
9422 // Ensure that the block token range contains the call to moveNext and it | 9009 // Ensure that the block token range contains the call to moveNext and it |
9423 // also starts the block at a different token position than the following | 9010 // also starts the block at a different token position than the following |
9424 // loop block. Both blocks can allocate contexts and if they have a matching | 9011 // loop block. Both blocks can allocate contexts and if they have a matching |
9425 // token position range, it can be an issue (cf. bug 26941). | 9012 // token position range, it can be an issue (cf. bug 26941). |
9426 OpenBlock(); // Implicit block around while loop. | 9013 OpenBlock(); // Implicit block around while loop. |
9427 | 9014 |
9428 const TokenPosition collection_pos = TokenPos(); | 9015 const TokenPosition collection_pos = TokenPos(); |
9429 AstNode* collection_expr = | 9016 AstNode* collection_expr = |
9430 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9017 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9431 ExpectToken(Token::kRPAREN); | 9018 ExpectToken(Token::kRPAREN); |
9432 | 9019 |
9433 // Generate implicit iterator variable and add to scope. | 9020 // Generate implicit iterator variable and add to scope. |
9434 // We could set the type of the implicit iterator variable to Iterator<T> | 9021 // We could set the type of the implicit iterator variable to Iterator<T> |
9435 // where T is the type of the for loop variable. However, the type error | 9022 // where T is the type of the for loop variable. However, the type error |
9436 // would refer to the compiler generated iterator and could confuse the user. | 9023 // would refer to the compiler generated iterator and could confuse the user. |
9437 // It is better to leave the iterator untyped and postpone the type error | 9024 // It is better to leave the iterator untyped and postpone the type error |
9438 // until the loop variable is assigned to. | 9025 // until the loop variable is assigned to. |
9439 const AbstractType& iterator_type = Object::dynamic_type(); | 9026 const AbstractType& iterator_type = Object::dynamic_type(); |
9440 LocalVariable* iterator_var = new(Z) LocalVariable( | 9027 LocalVariable* iterator_var = new (Z) LocalVariable( |
9441 collection_pos, | 9028 collection_pos, collection_pos, Symbols::ForInIter(), iterator_type); |
9442 collection_pos, Symbols::ForInIter(), iterator_type); | |
9443 current_block_->scope->AddVariable(iterator_var); | 9029 current_block_->scope->AddVariable(iterator_var); |
9444 | 9030 |
9445 // Generate initialization of iterator variable. | 9031 // Generate initialization of iterator variable. |
9446 ArgumentListNode* no_args = new(Z) ArgumentListNode(collection_pos); | 9032 ArgumentListNode* no_args = new (Z) ArgumentListNode(collection_pos); |
9447 AstNode* get_iterator = new(Z) InstanceGetterNode( | 9033 AstNode* get_iterator = new (Z) |
9448 collection_pos, collection_expr, Symbols::Iterator()); | 9034 InstanceGetterNode(collection_pos, collection_expr, Symbols::Iterator()); |
9449 AstNode* iterator_init = | 9035 AstNode* iterator_init = |
9450 new(Z) StoreLocalNode(collection_pos, iterator_var, get_iterator); | 9036 new (Z) StoreLocalNode(collection_pos, iterator_var, get_iterator); |
9451 current_block_->statements->Add(iterator_init); | 9037 current_block_->statements->Add(iterator_init); |
9452 | 9038 |
9453 // Generate while loop condition. | 9039 // Generate while loop condition. |
9454 AstNode* iterator_moveNext = new(Z) InstanceCallNode( | 9040 AstNode* iterator_moveNext = new (Z) InstanceCallNode( |
9455 collection_pos, | 9041 collection_pos, new (Z) LoadLocalNode(collection_pos, iterator_var), |
9456 new(Z) LoadLocalNode(collection_pos, iterator_var), | 9042 Symbols::MoveNext(), no_args); |
9457 Symbols::MoveNext(), | |
9458 no_args); | |
9459 | 9043 |
9460 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 9044 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
9461 // here, but that does not work well because we have to insert an implicit | 9045 // here, but that does not work well because we have to insert an implicit |
9462 // variable assignment and potentially a variable declaration in the | 9046 // variable assignment and potentially a variable declaration in the |
9463 // loop body. | 9047 // loop body. |
9464 OpenLoopBlock(); | 9048 OpenLoopBlock(); |
9465 current_block_->scope->AddLabel(label); | 9049 current_block_->scope->AddLabel(label); |
9466 const TokenPosition loop_var_assignment_pos = TokenPos(); | 9050 const TokenPosition loop_var_assignment_pos = TokenPos(); |
9467 | 9051 |
9468 AstNode* iterator_current = new(Z) InstanceGetterNode( | 9052 AstNode* iterator_current = new (Z) InstanceGetterNode( |
9469 loop_var_assignment_pos, | 9053 loop_var_assignment_pos, |
9470 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 9054 new (Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
9471 Symbols::Current()); | 9055 Symbols::Current()); |
9472 | 9056 |
9473 // Generate assignment of next iterator value to loop variable. | 9057 // Generate assignment of next iterator value to loop variable. |
9474 AstNode* loop_var_assignment = NULL; | 9058 AstNode* loop_var_assignment = NULL; |
9475 if (new_loop_var) { | 9059 if (new_loop_var) { |
9476 // The for loop variable is new for each iteration. | 9060 // The for loop variable is new for each iteration. |
9477 // Create a variable and add it to the loop body scope. | 9061 // Create a variable and add it to the loop body scope. |
9478 LocalVariable* loop_var = | 9062 LocalVariable* loop_var = new (Z) LocalVariable( |
9479 new(Z) LocalVariable(loop_var_pos, | 9063 loop_var_pos, loop_var_assignment_pos, *loop_var_name, loop_var_type); |
9480 loop_var_assignment_pos, | |
9481 *loop_var_name, | |
9482 loop_var_type); | |
9483 if (loop_var_is_final) { | 9064 if (loop_var_is_final) { |
9484 loop_var->set_is_final(); | 9065 loop_var->set_is_final(); |
9485 } | 9066 } |
9486 current_block_->scope->AddVariable(loop_var); | 9067 current_block_->scope->AddVariable(loop_var); |
9487 loop_var_assignment = new(Z) StoreLocalNode( | 9068 loop_var_assignment = new (Z) |
9488 loop_var_assignment_pos, loop_var, iterator_current); | 9069 StoreLocalNode(loop_var_assignment_pos, loop_var, iterator_current); |
9489 } else { | 9070 } else { |
9490 AstNode* loop_var_primary = | 9071 AstNode* loop_var_primary = |
9491 ResolveIdent(loop_var_pos, *loop_var_name, false); | 9072 ResolveIdent(loop_var_pos, *loop_var_name, false); |
9492 ASSERT(!loop_var_primary->IsPrimaryNode()); | 9073 ASSERT(!loop_var_primary->IsPrimaryNode()); |
9493 loop_var_assignment = CreateAssignmentNode(loop_var_primary, | 9074 loop_var_assignment = |
9494 iterator_current, | 9075 CreateAssignmentNode(loop_var_primary, iterator_current, loop_var_name, |
9495 loop_var_name, | 9076 loop_var_assignment_pos); |
9496 loop_var_assignment_pos); | |
9497 ASSERT(loop_var_assignment != NULL); | 9077 ASSERT(loop_var_assignment != NULL); |
9498 } | 9078 } |
9499 current_block_->statements->Add(loop_var_assignment); | 9079 current_block_->statements->Add(loop_var_assignment); |
9500 | 9080 |
9501 // Now parse the for-in loop statement or block. | 9081 // Now parse the for-in loop statement or block. |
9502 if (CurrentToken() == Token::kLBRACE) { | 9082 if (CurrentToken() == Token::kLBRACE) { |
9503 ConsumeToken(); | 9083 ConsumeToken(); |
9504 ParseStatementSequence(); | 9084 ParseStatementSequence(); |
9505 ExpectToken(Token::kRBRACE); | 9085 ExpectToken(Token::kRBRACE); |
9506 } else { | 9086 } else { |
9507 AstNode* statement = ParseStatement(); | 9087 AstNode* statement = ParseStatement(); |
9508 if (statement != NULL) { | 9088 if (statement != NULL) { |
9509 current_block_->statements->Add(statement); | 9089 current_block_->statements->Add(statement); |
9510 } | 9090 } |
9511 } | 9091 } |
9512 | 9092 |
9513 SequenceNode* for_loop_statement = CloseBlock(); | 9093 SequenceNode* for_loop_statement = CloseBlock(); |
9514 | 9094 |
9515 AstNode* while_statement = new(Z) WhileNode( | 9095 AstNode* while_statement = new (Z) |
9516 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); | 9096 WhileNode(forin_pos, label, iterator_moveNext, NULL, for_loop_statement); |
9517 current_block_->statements->Add(while_statement); | 9097 current_block_->statements->Add(while_statement); |
9518 | 9098 |
9519 return CloseBlock(); // Implicit block around while loop. | 9099 return CloseBlock(); // Implicit block around while loop. |
9520 } | 9100 } |
9521 | 9101 |
9522 | 9102 |
9523 AstNode* Parser::ParseForStatement(String* label_name) { | 9103 AstNode* Parser::ParseForStatement(String* label_name) { |
9524 TRACE_PARSER("ParseForStatement"); | 9104 TRACE_PARSER("ParseForStatement"); |
9525 const TokenPosition for_pos = TokenPos(); | 9105 const TokenPosition for_pos = TokenPos(); |
9526 ConsumeToken(); | 9106 ConsumeToken(); |
(...skipping 12 matching lines...) Expand all Loading... |
9539 if (IsVariableDeclaration()) { | 9119 if (IsVariableDeclaration()) { |
9540 initializer = ParseVariableDeclarationList(); | 9120 initializer = ParseVariableDeclarationList(); |
9541 } else { | 9121 } else { |
9542 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9122 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9543 } | 9123 } |
9544 } | 9124 } |
9545 ExpectSemicolon(); | 9125 ExpectSemicolon(); |
9546 AstNode* condition = NULL; | 9126 AstNode* condition = NULL; |
9547 SequenceNode* condition_preamble = NULL; | 9127 SequenceNode* condition_preamble = NULL; |
9548 if (CurrentToken() != Token::kSEMICOLON) { | 9128 if (CurrentToken() != Token::kSEMICOLON) { |
9549 condition = ParseAwaitableExpr( | 9129 condition = |
9550 kAllowConst, kConsumeCascades, &condition_preamble); | 9130 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &condition_preamble); |
9551 } | 9131 } |
9552 ExpectSemicolon(); | 9132 ExpectSemicolon(); |
9553 AstNode* increment = NULL; | 9133 AstNode* increment = NULL; |
9554 const TokenPosition incr_pos = TokenPos(); | 9134 const TokenPosition incr_pos = TokenPos(); |
9555 if (CurrentToken() != Token::kRPAREN) { | 9135 if (CurrentToken() != Token::kRPAREN) { |
9556 increment = ParseAwaitableExprList(); | 9136 increment = ParseAwaitableExprList(); |
9557 } | 9137 } |
9558 ExpectToken(Token::kRPAREN); | 9138 ExpectToken(Token::kRPAREN); |
9559 const bool parsing_loop_body = true; | 9139 const bool parsing_loop_body = true; |
9560 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 9140 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
9561 | 9141 |
9562 // Check whether any of the variables in the initializer part of | 9142 // Check whether any of the variables in the initializer part of |
9563 // the for statement are captured by a closure. If so, we insert a | 9143 // the for statement are captured by a closure. If so, we insert a |
9564 // node that creates a new Context for the loop variable before | 9144 // node that creates a new Context for the loop variable before |
9565 // the increment expression is evaluated. | 9145 // the increment expression is evaluated. |
9566 for (int i = 0; i < init_scope->num_variables(); i++) { | 9146 for (int i = 0; i < init_scope->num_variables(); i++) { |
9567 if (init_scope->VariableAt(i)->is_captured() && | 9147 if (init_scope->VariableAt(i)->is_captured() && |
9568 (init_scope->VariableAt(i)->owner() == init_scope)) { | 9148 (init_scope->VariableAt(i)->owner() == init_scope)) { |
9569 SequenceNode* incr_sequence = new(Z) SequenceNode(incr_pos, NULL); | 9149 SequenceNode* incr_sequence = new (Z) SequenceNode(incr_pos, NULL); |
9570 incr_sequence->Add(new(Z) CloneContextNode(for_pos)); | 9150 incr_sequence->Add(new (Z) CloneContextNode(for_pos)); |
9571 if (increment != NULL) { | 9151 if (increment != NULL) { |
9572 incr_sequence->Add(increment); | 9152 incr_sequence->Add(increment); |
9573 } | 9153 } |
9574 increment = incr_sequence; | 9154 increment = incr_sequence; |
9575 break; | 9155 break; |
9576 } | 9156 } |
9577 } | 9157 } |
9578 AstNode* for_node = new(Z) ForNode( | 9158 AstNode* for_node = new (Z) |
9579 for_pos, | 9159 ForNode(for_pos, label, NodeAsSequenceNode(init_pos, initializer, NULL), |
9580 label, | 9160 condition, condition_preamble, |
9581 NodeAsSequenceNode(init_pos, initializer, NULL), | 9161 NodeAsSequenceNode(incr_pos, increment, NULL), body); |
9582 condition, | |
9583 condition_preamble, | |
9584 NodeAsSequenceNode(incr_pos, increment, NULL), | |
9585 body); | |
9586 current_block_->statements->Add(for_node); | 9162 current_block_->statements->Add(for_node); |
9587 return CloseBlock(); | 9163 return CloseBlock(); |
9588 } | 9164 } |
9589 | 9165 |
9590 | 9166 |
9591 // Calling VM-internal helpers, uses implementation core library. | 9167 // Calling VM-internal helpers, uses implementation core library. |
9592 AstNode* Parser::MakeStaticCall(const String& cls_name, | 9168 AstNode* Parser::MakeStaticCall(const String& cls_name, |
9593 const String& func_name, | 9169 const String& func_name, |
9594 ArgumentListNode* arguments) { | 9170 ArgumentListNode* arguments) { |
9595 const Class& cls = Class::Handle(Z, Library::LookupCoreClass(cls_name)); | 9171 const Class& cls = Class::Handle(Z, Library::LookupCoreClass(cls_name)); |
9596 ASSERT(!cls.IsNull()); | 9172 ASSERT(!cls.IsNull()); |
9597 const Function& func = Function::ZoneHandle(Z, | 9173 const Function& func = Function::ZoneHandle( |
9598 Resolver::ResolveStatic(cls, | 9174 Z, Resolver::ResolveStatic(cls, func_name, arguments->length(), |
9599 func_name, | 9175 arguments->names())); |
9600 arguments->length(), | |
9601 arguments->names())); | |
9602 ASSERT(!func.IsNull()); | 9176 ASSERT(!func.IsNull()); |
9603 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); | 9177 return new (Z) StaticCallNode(arguments->token_pos(), func, arguments); |
9604 } | 9178 } |
9605 | 9179 |
9606 | 9180 |
9607 AstNode* Parser::ParseAssertStatement(bool is_const) { | 9181 AstNode* Parser::ParseAssertStatement(bool is_const) { |
9608 TRACE_PARSER("ParseAssertStatement"); | 9182 TRACE_PARSER("ParseAssertStatement"); |
9609 ConsumeToken(); // Consume assert keyword. | 9183 ConsumeToken(); // Consume assert keyword. |
9610 ExpectToken(Token::kLPAREN); | 9184 ExpectToken(Token::kLPAREN); |
9611 const TokenPosition condition_pos = TokenPos(); | 9185 const TokenPosition condition_pos = TokenPos(); |
9612 if (!I->asserts()) { | 9186 if (!I->asserts()) { |
9613 SkipExpr(); | 9187 SkipExpr(); |
9614 ExpectToken(Token::kRPAREN); | 9188 ExpectToken(Token::kRPAREN); |
9615 return NULL; | 9189 return NULL; |
9616 } | 9190 } |
9617 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9191 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9618 if (is_const && !condition->IsPotentiallyConst()) { | 9192 if (is_const && !condition->IsPotentiallyConst()) { |
9619 ReportError(condition_pos, | 9193 ReportError(condition_pos, |
9620 "initializer assert expression must be compile time constant."); | 9194 "initializer assert expression must be compile time constant."); |
9621 } | 9195 } |
9622 const TokenPosition condition_end = TokenPos(); | 9196 const TokenPosition condition_end = TokenPos(); |
9623 ExpectToken(Token::kRPAREN); | 9197 ExpectToken(Token::kRPAREN); |
9624 | 9198 |
9625 ArgumentListNode* arguments = new(Z) ArgumentListNode(condition_pos); | 9199 ArgumentListNode* arguments = new (Z) ArgumentListNode(condition_pos); |
9626 arguments->Add(condition); | 9200 arguments->Add(condition); |
9627 arguments->Add(new(Z) LiteralNode(condition_pos, | 9201 arguments->Add(new (Z) LiteralNode( |
| 9202 condition_pos, |
9628 Integer::ZoneHandle(Z, Integer::New(condition_pos.value(), Heap::kOld)))); | 9203 Integer::ZoneHandle(Z, Integer::New(condition_pos.value(), Heap::kOld)))); |
9629 arguments->Add(new(Z) LiteralNode(condition_end, | 9204 arguments->Add(new (Z) LiteralNode( |
| 9205 condition_end, |
9630 Integer::ZoneHandle(Z, Integer::New(condition_end.value(), Heap::kOld)))); | 9206 Integer::ZoneHandle(Z, Integer::New(condition_end.value(), Heap::kOld)))); |
9631 AstNode* assert_throw = MakeStaticCall(Symbols::AssertionError(), | 9207 AstNode* assert_throw = MakeStaticCall( |
| 9208 Symbols::AssertionError(), |
9632 Library::PrivateCoreLibName(is_const ? Symbols::CheckConstAssertion() | 9209 Library::PrivateCoreLibName(is_const ? Symbols::CheckConstAssertion() |
9633 : Symbols::CheckAssertion()), | 9210 : Symbols::CheckAssertion()), |
9634 arguments); | 9211 arguments); |
9635 | 9212 |
9636 return assert_throw; | 9213 return assert_throw; |
9637 } | 9214 } |
9638 | 9215 |
9639 | 9216 |
9640 // Populate local scope of the catch block with the catch parameters. | 9217 // Populate local scope of the catch block with the catch parameters. |
9641 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 9218 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
9642 CatchParamDesc* stack_trace_param, | 9219 CatchParamDesc* stack_trace_param, |
9643 LocalScope* scope) { | 9220 LocalScope* scope) { |
9644 if (exception_param->name != NULL) { | 9221 if (exception_param->name != NULL) { |
9645 LocalVariable* var = new(Z) LocalVariable( | 9222 LocalVariable* var = new (Z) |
9646 exception_param->token_pos, | 9223 LocalVariable(exception_param->token_pos, exception_param->token_pos, |
9647 exception_param->token_pos, | 9224 *exception_param->name, *exception_param->type); |
9648 *exception_param->name, | |
9649 *exception_param->type); | |
9650 var->set_is_final(); | 9225 var->set_is_final(); |
9651 bool added_to_scope = scope->AddVariable(var); | 9226 bool added_to_scope = scope->AddVariable(var); |
9652 ASSERT(added_to_scope); | 9227 ASSERT(added_to_scope); |
9653 exception_param->var = var; | 9228 exception_param->var = var; |
9654 } | 9229 } |
9655 if (stack_trace_param->name != NULL) { | 9230 if (stack_trace_param->name != NULL) { |
9656 LocalVariable* var = new(Z) LocalVariable( | 9231 LocalVariable* var = new (Z) LocalVariable( |
9657 stack_trace_param->token_pos, | 9232 stack_trace_param->token_pos, stack_trace_param->token_pos, |
9658 stack_trace_param->token_pos, | 9233 *stack_trace_param->name, *stack_trace_param->type); |
9659 *stack_trace_param->name, | |
9660 *stack_trace_param->type); | |
9661 var->set_is_final(); | 9234 var->set_is_final(); |
9662 bool added_to_scope = scope->AddVariable(var); | 9235 bool added_to_scope = scope->AddVariable(var); |
9663 if (!added_to_scope) { | 9236 if (!added_to_scope) { |
9664 // The name of the exception param is reused for the stack trace param. | 9237 // The name of the exception param is reused for the stack trace param. |
9665 ReportError(stack_trace_param->token_pos, | 9238 ReportError(stack_trace_param->token_pos, |
9666 "name '%s' already exists in scope", | 9239 "name '%s' already exists in scope", |
9667 stack_trace_param->name->ToCString()); | 9240 stack_trace_param->name->ToCString()); |
9668 } | 9241 } |
9669 stack_trace_param->var = var; | 9242 stack_trace_param->var = var; |
9670 } | 9243 } |
(...skipping 11 matching lines...) Expand all Loading... |
9682 LocalVariable* saved_stack_trace_var) { | 9255 LocalVariable* saved_stack_trace_var) { |
9683 ASSERT(innermost_function().IsAsyncClosure() || | 9256 ASSERT(innermost_function().IsAsyncClosure() || |
9684 innermost_function().IsAsyncFunction() || | 9257 innermost_function().IsAsyncFunction() || |
9685 innermost_function().IsSyncGenClosure() || | 9258 innermost_function().IsSyncGenClosure() || |
9686 innermost_function().IsSyncGenerator() || | 9259 innermost_function().IsSyncGenerator() || |
9687 innermost_function().IsAsyncGenClosure() || | 9260 innermost_function().IsAsyncGenClosure() || |
9688 innermost_function().IsAsyncGenerator()); | 9261 innermost_function().IsAsyncGenerator()); |
9689 | 9262 |
9690 ASSERT(saved_exception_var != NULL); | 9263 ASSERT(saved_exception_var != NULL); |
9691 ASSERT(exception_var != NULL); | 9264 ASSERT(exception_var != NULL); |
9692 statements->Add(new(Z) StoreLocalNode( | 9265 statements->Add(new (Z) StoreLocalNode( |
9693 TokenPosition::kNoSource, | 9266 TokenPosition::kNoSource, saved_exception_var, |
9694 saved_exception_var, | 9267 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
9695 new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); | |
9696 | 9268 |
9697 ASSERT(saved_stack_trace_var != NULL); | 9269 ASSERT(saved_stack_trace_var != NULL); |
9698 ASSERT(stack_trace_var != NULL); | 9270 ASSERT(stack_trace_var != NULL); |
9699 statements->Add(new(Z) StoreLocalNode( | 9271 statements->Add(new (Z) StoreLocalNode( |
9700 TokenPosition::kNoSource, | 9272 TokenPosition::kNoSource, saved_stack_trace_var, |
9701 saved_stack_trace_var, | 9273 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
9702 new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); | |
9703 } | 9274 } |
9704 | 9275 |
9705 | 9276 |
9706 SequenceNode* Parser::EnsureFinallyClause( | 9277 SequenceNode* Parser::EnsureFinallyClause( |
9707 bool parse, | 9278 bool parse, |
9708 bool is_async, | 9279 bool is_async, |
9709 LocalVariable* exception_var, | 9280 LocalVariable* exception_var, |
9710 LocalVariable* stack_trace_var, | 9281 LocalVariable* stack_trace_var, |
9711 LocalVariable* rethrow_exception_var, | 9282 LocalVariable* rethrow_exception_var, |
9712 LocalVariable* rethrow_stack_trace_var) { | 9283 LocalVariable* rethrow_stack_trace_var) { |
(...skipping 18 matching lines...) Expand all Loading... |
9731 } | 9302 } |
9732 // In case of async closures we need to restore the saved try context of an | 9303 // In case of async closures we need to restore the saved try context of an |
9733 // outer try block (if it exists). The current try block has already been | 9304 // outer try block (if it exists). The current try block has already been |
9734 // removed from the stack of try blocks. | 9305 // removed from the stack of try blocks. |
9735 if (is_async) { | 9306 if (is_async) { |
9736 if (try_stack_ != NULL) { | 9307 if (try_stack_ != NULL) { |
9737 LocalScope* scope = try_stack_->try_block()->scope; | 9308 LocalScope* scope = try_stack_->try_block()->scope; |
9738 if (scope->function_level() == current_block_->scope->function_level()) { | 9309 if (scope->function_level() == current_block_->scope->function_level()) { |
9739 LocalVariable* saved_try_ctx = | 9310 LocalVariable* saved_try_ctx = |
9740 LookupSavedTryContextVar(scope->parent()); | 9311 LookupSavedTryContextVar(scope->parent()); |
9741 LocalVariable* async_saved_try_ctx = LookupAsyncSavedTryContextVar(T, | 9312 LocalVariable* async_saved_try_ctx = LookupAsyncSavedTryContextVar( |
9742 async_temp_scope_, try_stack_->try_index()); | 9313 T, async_temp_scope_, try_stack_->try_index()); |
9743 current_block_->statements->Add( | 9314 current_block_->statements->Add(new (Z) StoreLocalNode( |
9744 new (Z) StoreLocalNode( | 9315 TokenPosition::kNoSource, saved_try_ctx, |
9745 TokenPosition::kNoSource, | 9316 new (Z) |
9746 saved_try_ctx, | 9317 LoadLocalNode(TokenPosition::kNoSource, async_saved_try_ctx))); |
9747 new (Z) LoadLocalNode(TokenPosition::kNoSource, | |
9748 async_saved_try_ctx))); | |
9749 } | 9318 } |
9750 } | 9319 } |
9751 // We need to save the exception variables as in catch clauses, whether | 9320 // We need to save the exception variables as in catch clauses, whether |
9752 // there is an outer try or not. Note that this is only necessary if the | 9321 // there is an outer try or not. Note that this is only necessary if the |
9753 // finally clause contains an await or yield. | 9322 // finally clause contains an await or yield. |
9754 // TODO(hausner): Optimize. | 9323 // TODO(hausner): Optimize. |
9755 SaveExceptionAndStacktrace(current_block_->statements, | 9324 SaveExceptionAndStacktrace(current_block_->statements, exception_var, |
9756 exception_var, | 9325 stack_trace_var, rethrow_exception_var, |
9757 stack_trace_var, | |
9758 rethrow_exception_var, | |
9759 rethrow_stack_trace_var); | 9326 rethrow_stack_trace_var); |
9760 } | 9327 } |
9761 | 9328 |
9762 if (parse) { | 9329 if (parse) { |
9763 ParseStatementSequence(); | 9330 ParseStatementSequence(); |
9764 ExpectToken(Token::kRBRACE); | 9331 ExpectToken(Token::kRBRACE); |
9765 } | 9332 } |
9766 SequenceNode* finally_clause = CloseBlock(); | 9333 SequenceNode* finally_clause = CloseBlock(); |
9767 if (try_stack_ != NULL) { | 9334 if (try_stack_ != NULL) { |
9768 try_stack_->exit_finally(); | 9335 try_stack_->exit_finally(); |
9769 } | 9336 } |
9770 return finally_clause; | 9337 return finally_clause; |
9771 } | 9338 } |
9772 | 9339 |
9773 | 9340 |
9774 void Parser::PushTry(Block* try_block) { | 9341 void Parser::PushTry(Block* try_block) { |
9775 intptr_t try_index = AllocateTryIndex(); | 9342 intptr_t try_index = AllocateTryIndex(); |
9776 try_stack_ = new(Z) TryStack(try_block, try_stack_, try_index); | 9343 try_stack_ = new (Z) TryStack(try_block, try_stack_, try_index); |
9777 } | 9344 } |
9778 | 9345 |
9779 | 9346 |
9780 Parser::TryStack* Parser::PopTry() { | 9347 Parser::TryStack* Parser::PopTry() { |
9781 TryStack* innermost_try = try_stack_; | 9348 TryStack* innermost_try = try_stack_; |
9782 try_stack_ = try_stack_->outer_try(); | 9349 try_stack_ = try_stack_->outer_try(); |
9783 return innermost_try; | 9350 return innermost_try; |
9784 } | 9351 } |
9785 | 9352 |
9786 | 9353 |
9787 void Parser::AddNodeForFinallyInlining(AstNode* node) { | 9354 void Parser::AddNodeForFinallyInlining(AstNode* node) { |
9788 if (node == NULL) { | 9355 if (node == NULL) { |
9789 return; | 9356 return; |
9790 } | 9357 } |
9791 ASSERT(node->IsReturnNode() || node->IsJumpNode()); | 9358 ASSERT(node->IsReturnNode() || node->IsJumpNode()); |
9792 const intptr_t func_level = FunctionLevel(); | 9359 const intptr_t func_level = FunctionLevel(); |
9793 TryStack* iterator = try_stack_; | 9360 TryStack* iterator = try_stack_; |
9794 while ((iterator != NULL) && | 9361 while ((iterator != NULL) && |
9795 (iterator->try_block()->scope->function_level() == func_level)) { | 9362 (iterator->try_block()->scope->function_level() == func_level)) { |
9796 // For continue and break node check if the target label is in scope. | 9363 // For continue and break node check if the target label is in scope. |
9797 if (node->IsJumpNode()) { | 9364 if (node->IsJumpNode()) { |
9798 SourceLabel* label = node->AsJumpNode()->label(); | 9365 SourceLabel* label = node->AsJumpNode()->label(); |
9799 ASSERT(label != NULL); | 9366 ASSERT(label != NULL); |
9800 LocalScope* try_scope = iterator->try_block()->scope; | 9367 LocalScope* try_scope = iterator->try_block()->scope; |
9801 // If the label is defined in a scope which is a child (nested scope) | 9368 // If the label is defined in a scope which is a child (nested scope) |
9802 // of the try scope then we are not breaking out of this try block | 9369 // of the try scope then we are not breaking out of this try block |
9803 // so we do not need to inline the finally code. Otherwise we need | 9370 // so we do not need to inline the finally code. Otherwise we need |
9804 // to inline the finally code of this try block and then move on to the | 9371 // to inline the finally code of this try block and then move on to the |
9805 // next outer try block. | 9372 // next outer try block. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9866 GrowableArray<SequenceNode*> catch_blocks; | 9433 GrowableArray<SequenceNode*> catch_blocks; |
9867 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { | 9434 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { |
9868 // Open a block that contains the if or an unconditional body. It's | 9435 // Open a block that contains the if or an unconditional body. It's |
9869 // closed in the loop that builds the if-then-else nest. | 9436 // closed in the loop that builds the if-then-else nest. |
9870 OpenBlock(); | 9437 OpenBlock(); |
9871 const TokenPosition catch_pos = TokenPos(); | 9438 const TokenPosition catch_pos = TokenPos(); |
9872 CatchParamDesc exception_param; | 9439 CatchParamDesc exception_param; |
9873 CatchParamDesc stack_trace_param; | 9440 CatchParamDesc stack_trace_param; |
9874 if (IsSymbol(Symbols::On())) { | 9441 if (IsSymbol(Symbols::On())) { |
9875 ConsumeToken(); | 9442 ConsumeToken(); |
9876 exception_param.type = &AbstractType::ZoneHandle(Z, | 9443 exception_param.type = &AbstractType::ZoneHandle( |
9877 ParseType(ClassFinalizer::kCanonicalize)); | 9444 Z, ParseType(ClassFinalizer::kCanonicalize)); |
9878 } else { | 9445 } else { |
9879 exception_param.type = &Object::dynamic_type(); | 9446 exception_param.type = &Object::dynamic_type(); |
9880 } | 9447 } |
9881 if (CurrentToken() == Token::kCATCH) { | 9448 if (CurrentToken() == Token::kCATCH) { |
9882 ConsumeToken(); // Consume the 'catch'. | 9449 ConsumeToken(); // Consume the 'catch'. |
9883 ExpectToken(Token::kLPAREN); | 9450 ExpectToken(Token::kLPAREN); |
9884 exception_param.token_pos = TokenPos(); | 9451 exception_param.token_pos = TokenPos(); |
9885 exception_param.name = ExpectIdentifier("identifier expected"); | 9452 exception_param.name = ExpectIdentifier("identifier expected"); |
9886 if (CurrentToken() == Token::kCOMMA) { | 9453 if (CurrentToken() == Token::kCOMMA) { |
9887 ConsumeToken(); | 9454 ConsumeToken(); |
(...skipping 12 matching lines...) Expand all Loading... |
9900 // captured :saved_exception_var and :saved_stack_trace_var. | 9467 // captured :saved_exception_var and :saved_stack_trace_var. |
9901 // 3) Nested block with source code from catch clause block. | 9468 // 3) Nested block with source code from catch clause block. |
9902 OpenBlock(); | 9469 OpenBlock(); |
9903 AddCatchParamsToScope(&exception_param, &stack_trace_param, | 9470 AddCatchParamsToScope(&exception_param, &stack_trace_param, |
9904 current_block_->scope); | 9471 current_block_->scope); |
9905 | 9472 |
9906 if (exception_param.var != NULL) { | 9473 if (exception_param.var != NULL) { |
9907 // Generate code to load the exception object (:exception_var) into | 9474 // Generate code to load the exception object (:exception_var) into |
9908 // the exception variable specified in this block. | 9475 // the exception variable specified in this block. |
9909 ASSERT(exception_var != NULL); | 9476 ASSERT(exception_var != NULL); |
9910 current_block_->statements->Add(new(Z) StoreLocalNode( | 9477 current_block_->statements->Add(new (Z) StoreLocalNode( |
9911 catch_pos, exception_param.var, new(Z) LoadLocalNode( | 9478 catch_pos, exception_param.var, |
9912 catch_pos, exception_var))); | 9479 new (Z) LoadLocalNode(catch_pos, exception_var))); |
9913 } | 9480 } |
9914 if (stack_trace_param.var != NULL) { | 9481 if (stack_trace_param.var != NULL) { |
9915 // A stack trace variable is specified in this block, so generate code | 9482 // A stack trace variable is specified in this block, so generate code |
9916 // to load the stack trace object (:stack_trace_var) into the stack | 9483 // to load the stack trace object (:stack_trace_var) into the stack |
9917 // trace variable specified in this block. | 9484 // trace variable specified in this block. |
9918 *needs_stack_trace = true; | 9485 *needs_stack_trace = true; |
9919 ASSERT(stack_trace_var != NULL); | 9486 ASSERT(stack_trace_var != NULL); |
9920 current_block_->statements->Add(new(Z) StoreLocalNode( | 9487 current_block_->statements->Add(new (Z) StoreLocalNode( |
9921 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode( | 9488 catch_pos, stack_trace_param.var, |
9922 catch_pos, stack_trace_var))); | 9489 new (Z) LoadLocalNode(catch_pos, stack_trace_var))); |
9923 } | 9490 } |
9924 | 9491 |
9925 // Add nested block with user-defined code. This block allows | 9492 // Add nested block with user-defined code. This block allows |
9926 // declarations in the body to shadow the catch parameters. | 9493 // declarations in the body to shadow the catch parameters. |
9927 CheckToken(Token::kLBRACE); | 9494 CheckToken(Token::kLBRACE); |
9928 | 9495 |
9929 current_block_->statements->Add(ParseNestedStatement(false, NULL)); | 9496 current_block_->statements->Add(ParseNestedStatement(false, NULL)); |
9930 catch_blocks.Add(CloseBlock()); | 9497 catch_blocks.Add(CloseBlock()); |
9931 | 9498 |
9932 const bool is_bad_type = | 9499 const bool is_bad_type = exception_param.type->IsMalformed() || |
9933 exception_param.type->IsMalformed() || | 9500 exception_param.type->IsMalbounded(); |
9934 exception_param.type->IsMalbounded(); | |
9935 if (exception_param.type->IsDynamicType() || is_bad_type) { | 9501 if (exception_param.type->IsDynamicType() || is_bad_type) { |
9936 // There is no exception type or else it is malformed or malbounded. | 9502 // There is no exception type or else it is malformed or malbounded. |
9937 // In the first case, unconditionally execute the catch body. In the | 9503 // In the first case, unconditionally execute the catch body. In the |
9938 // second case, unconditionally throw. | 9504 // second case, unconditionally throw. |
9939 generic_catch_seen = true; | 9505 generic_catch_seen = true; |
9940 type_tests.Add(new(Z) LiteralNode(catch_pos, Bool::True())); | 9506 type_tests.Add(new (Z) LiteralNode(catch_pos, Bool::True())); |
9941 if (is_bad_type) { | 9507 if (is_bad_type) { |
9942 // Replace the body with one that throws. | 9508 // Replace the body with one that throws. |
9943 SequenceNode* block = new(Z) SequenceNode(catch_pos, NULL); | 9509 SequenceNode* block = new (Z) SequenceNode(catch_pos, NULL); |
9944 block->Add(ThrowTypeError(catch_pos, *exception_param.type)); | 9510 block->Add(ThrowTypeError(catch_pos, *exception_param.type)); |
9945 catch_blocks.Last() = block; | 9511 catch_blocks.Last() = block; |
9946 } | 9512 } |
9947 // This catch clause will handle all exceptions. We can safely forget | 9513 // This catch clause will handle all exceptions. We can safely forget |
9948 // all previous catch clause types. | 9514 // all previous catch clause types. |
9949 handler_types.SetLength(0); | 9515 handler_types.SetLength(0); |
9950 handler_types.Add(*exception_param.type); | 9516 handler_types.Add(*exception_param.type); |
9951 } else { | 9517 } else { |
9952 // Has a type specification that is not malformed or malbounded. Now | 9518 // Has a type specification that is not malformed or malbounded. Now |
9953 // form an 'if type check' to guard the catch handler code. | 9519 // form an 'if type check' to guard the catch handler code. |
9954 if (!exception_param.type->IsInstantiated() && | 9520 if (!exception_param.type->IsInstantiated() && (FunctionLevel() > 0)) { |
9955 (FunctionLevel() > 0)) { | |
9956 // Make sure that the instantiator is captured. | 9521 // Make sure that the instantiator is captured. |
9957 CaptureInstantiator(); | 9522 CaptureInstantiator(); |
9958 } | 9523 } |
9959 TypeNode* exception_type = new(Z) TypeNode( | 9524 TypeNode* exception_type = |
9960 catch_pos, *exception_param.type); | 9525 new (Z) TypeNode(catch_pos, *exception_param.type); |
9961 AstNode* exception_value = new(Z) LoadLocalNode( | 9526 AstNode* exception_value = |
9962 catch_pos, exception_var); | 9527 new (Z) LoadLocalNode(catch_pos, exception_var); |
9963 if (!exception_type->type().IsInstantiated()) { | 9528 if (!exception_type->type().IsInstantiated()) { |
9964 EnsureExpressionTemp(); | 9529 EnsureExpressionTemp(); |
9965 } | 9530 } |
9966 type_tests.Add(new(Z) ComparisonNode( | 9531 type_tests.Add(new (Z) ComparisonNode(catch_pos, Token::kIS, |
9967 catch_pos, Token::kIS, exception_value, exception_type)); | 9532 exception_value, exception_type)); |
9968 | 9533 |
9969 // Do not add uninstantiated types (e.g. type parameter T or generic | 9534 // Do not add uninstantiated types (e.g. type parameter T or generic |
9970 // type List<T>), since the debugger won't be able to instantiate it | 9535 // type List<T>), since the debugger won't be able to instantiate it |
9971 // when walking the stack. | 9536 // when walking the stack. |
9972 // | 9537 // |
9973 // This means that the debugger is not able to determine whether an | 9538 // This means that the debugger is not able to determine whether an |
9974 // exception is caught if the catch clause uses generic types. It | 9539 // exception is caught if the catch clause uses generic types. It |
9975 // will report the exception as uncaught when in fact it might be | 9540 // will report the exception as uncaught when in fact it might be |
9976 // caught and handled when we unwind the stack. | 9541 // caught and handled when we unwind the stack. |
9977 if (!generic_catch_seen && exception_param.type->IsInstantiated()) { | 9542 if (!generic_catch_seen && exception_param.type->IsInstantiated()) { |
9978 handler_types.Add(*exception_param.type); | 9543 handler_types.Add(*exception_param.type); |
9979 } | 9544 } |
9980 } | 9545 } |
9981 | 9546 |
9982 ASSERT(type_tests.length() == catch_blocks.length()); | 9547 ASSERT(type_tests.length() == catch_blocks.length()); |
9983 } | 9548 } |
9984 | 9549 |
9985 // Build the if/then/else nest from the inside out. Keep the AST simple | 9550 // Build the if/then/else nest from the inside out. Keep the AST simple |
9986 // for the case of a single generic catch clause. The initial value of | 9551 // for the case of a single generic catch clause. The initial value of |
9987 // current is the last (innermost) else block if there were any catch | 9552 // current is the last (innermost) else block if there were any catch |
9988 // clauses. | 9553 // clauses. |
9989 SequenceNode* current = NULL; | 9554 SequenceNode* current = NULL; |
9990 if (!generic_catch_seen) { | 9555 if (!generic_catch_seen) { |
9991 // There isn't a generic catch clause so create a clause body that | 9556 // There isn't a generic catch clause so create a clause body that |
9992 // rethrows the exception. This includes the case that there were no | 9557 // rethrows the exception. This includes the case that there were no |
9993 // catch clauses. | 9558 // catch clauses. |
9994 // An await cannot possibly be executed inbetween the catch entry and here, | 9559 // An await cannot possibly be executed inbetween the catch entry and here, |
9995 // therefore, it is safe to rethrow the stack-based :exception_var instead | 9560 // therefore, it is safe to rethrow the stack-based :exception_var instead |
9996 // of the captured copy :saved_exception_var. | 9561 // of the captured copy :saved_exception_var. |
9997 current = new(Z) SequenceNode(handler_pos, NULL); | 9562 current = new (Z) SequenceNode(handler_pos, NULL); |
9998 current->Add(new(Z) ThrowNode( | 9563 current->Add(new (Z) ThrowNode( |
9999 handler_pos, | 9564 handler_pos, new (Z) LoadLocalNode(handler_pos, exception_var), |
10000 new(Z) LoadLocalNode(handler_pos, exception_var), | 9565 new (Z) LoadLocalNode(handler_pos, stack_trace_var))); |
10001 new(Z) LoadLocalNode(handler_pos, stack_trace_var))); | |
10002 } else if (type_tests.Last()->IsLiteralNode()) { | 9566 } else if (type_tests.Last()->IsLiteralNode()) { |
10003 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == | 9567 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == |
10004 Bool::True().raw()); | 9568 Bool::True().raw()); |
10005 // The last body is entered unconditionally. Start building the | 9569 // The last body is entered unconditionally. Start building the |
10006 // if/then/else nest with that body as the innermost else block. | 9570 // if/then/else nest with that body as the innermost else block. |
10007 // Note that it is nested inside an extra block which we opened | 9571 // Note that it is nested inside an extra block which we opened |
10008 // before we knew the body was entered unconditionally. | 9572 // before we knew the body was entered unconditionally. |
10009 type_tests.RemoveLast(); | 9573 type_tests.RemoveLast(); |
10010 current_block_->statements->Add(catch_blocks.RemoveLast()); | 9574 current_block_->statements->Add(catch_blocks.RemoveLast()); |
10011 current = CloseBlock(); | 9575 current = CloseBlock(); |
10012 } | 9576 } |
10013 // If the last body was entered conditionally and there is no need to add | 9577 // If the last body was entered conditionally and there is no need to add |
10014 // a rethrow, use an empty else body (current = NULL above). | 9578 // a rethrow, use an empty else body (current = NULL above). |
10015 while (!type_tests.is_empty()) { | 9579 while (!type_tests.is_empty()) { |
10016 AstNode* type_test = type_tests.RemoveLast(); | 9580 AstNode* type_test = type_tests.RemoveLast(); |
10017 SequenceNode* catch_block = catch_blocks.RemoveLast(); | 9581 SequenceNode* catch_block = catch_blocks.RemoveLast(); |
10018 current_block_->statements->Add(new(Z) IfNode( | 9582 current_block_->statements->Add(new (Z) IfNode( |
10019 type_test->token_pos(), type_test, catch_block, current)); | 9583 type_test->token_pos(), type_test, catch_block, current)); |
10020 current = CloseBlock(); | 9584 current = CloseBlock(); |
10021 } | 9585 } |
10022 // In case of async closures, restore :saved_try_context_var before executing | 9586 // In case of async closures, restore :saved_try_context_var before executing |
10023 // the catch clauses. | 9587 // the catch clauses. |
10024 if (is_async && (current != NULL)) { | 9588 if (is_async && (current != NULL)) { |
10025 ASSERT(try_stack_ != NULL); | 9589 ASSERT(try_stack_ != NULL); |
10026 SequenceNode* async_code = new(Z) SequenceNode(handler_pos, NULL); | 9590 SequenceNode* async_code = new (Z) SequenceNode(handler_pos, NULL); |
10027 const TryStack* try_block = try_stack_->outer_try(); | 9591 const TryStack* try_block = try_stack_->outer_try(); |
10028 if (try_block != NULL) { | 9592 if (try_block != NULL) { |
10029 LocalScope* scope = try_block->try_block()->scope; | 9593 LocalScope* scope = try_block->try_block()->scope; |
10030 if (scope->function_level() == current_block_->scope->function_level()) { | 9594 if (scope->function_level() == current_block_->scope->function_level()) { |
10031 LocalVariable* saved_try_ctx = | 9595 LocalVariable* saved_try_ctx = |
10032 LookupSavedTryContextVar(scope->parent()); | 9596 LookupSavedTryContextVar(scope->parent()); |
10033 LocalVariable* async_saved_try_ctx = LookupAsyncSavedTryContextVar(T, | 9597 LocalVariable* async_saved_try_ctx = LookupAsyncSavedTryContextVar( |
10034 async_temp_scope_, try_block->try_index()); | 9598 T, async_temp_scope_, try_block->try_index()); |
10035 async_code->Add( | 9599 async_code->Add(new (Z) StoreLocalNode( |
10036 new (Z) StoreLocalNode( | 9600 TokenPosition::kNoSource, saved_try_ctx, |
10037 TokenPosition::kNoSource, | 9601 new (Z) |
10038 saved_try_ctx, | 9602 LoadLocalNode(TokenPosition::kNoSource, async_saved_try_ctx))); |
10039 new (Z) LoadLocalNode(TokenPosition::kNoSource, | |
10040 async_saved_try_ctx))); | |
10041 } | 9603 } |
10042 } | 9604 } |
10043 SaveExceptionAndStacktrace(async_code, | 9605 SaveExceptionAndStacktrace(async_code, exception_var, stack_trace_var, |
10044 exception_var, | 9606 rethrow_exception_var, rethrow_stack_trace_var); |
10045 stack_trace_var, | |
10046 rethrow_exception_var, | |
10047 rethrow_stack_trace_var); | |
10048 // The async_code node sequence contains code to restore the context (if | 9607 // The async_code node sequence contains code to restore the context (if |
10049 // an outer try block is present) and code to save the exception and | 9608 // an outer try block is present) and code to save the exception and |
10050 // stack trace variables. | 9609 // stack trace variables. |
10051 // This async code is inserted before the current node sequence containing | 9610 // This async code is inserted before the current node sequence containing |
10052 // the chain of if/then/else handling all catch clauses. | 9611 // the chain of if/then/else handling all catch clauses. |
10053 async_code->Add(current); | 9612 async_code->Add(current); |
10054 current = async_code; | 9613 current = async_code; |
10055 } | 9614 } |
10056 return current; | 9615 return current; |
10057 } | 9616 } |
10058 | 9617 |
10059 | 9618 |
10060 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 9619 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
10061 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, | 9620 const String& async_saved_try_ctx_name = String::ZoneHandle( |
10062 Symbols::NewFormatted(T, | 9621 Z, Symbols::NewFormatted(T, "%s%d", |
10063 "%s%d", | 9622 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
10064 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 9623 last_used_try_index_ - 1)); |
10065 last_used_try_index_ - 1)); | 9624 LocalVariable* async_saved_try_ctx = |
10066 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( | 9625 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
10067 TokenPosition::kNoSource, | 9626 async_saved_try_ctx_name, Object::dynamic_type()); |
10068 TokenPosition::kNoSource, | |
10069 async_saved_try_ctx_name, | |
10070 Object::dynamic_type()); | |
10071 ASSERT(async_temp_scope_ != NULL); | 9627 ASSERT(async_temp_scope_ != NULL); |
10072 async_temp_scope_->AddVariable(async_saved_try_ctx); | 9628 async_temp_scope_->AddVariable(async_saved_try_ctx); |
10073 ASSERT(saved_try_context != NULL); | 9629 ASSERT(saved_try_context != NULL); |
10074 current_block_->statements->Add(new(Z) StoreLocalNode( | 9630 current_block_->statements->Add(new (Z) StoreLocalNode( |
10075 TokenPosition::kNoSource, | 9631 TokenPosition::kNoSource, async_saved_try_ctx, |
10076 async_saved_try_ctx, | 9632 new (Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context))); |
10077 new(Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context))); | |
10078 } | 9633 } |
10079 | 9634 |
10080 | 9635 |
10081 // We create three variables for exceptions: | 9636 // We create three variables for exceptions: |
10082 // ':saved_try_context_var' - Used to save the context before the start of | 9637 // ':saved_try_context_var' - Used to save the context before the start of |
10083 // the try block. The context register is | 9638 // the try block. The context register is |
10084 // restored from this variable before | 9639 // restored from this variable before |
10085 // processing the catch block handler. | 9640 // processing the catch block handler. |
10086 // ':exception_var' - Used to save the current exception object that was | 9641 // ':exception_var' - Used to save the current exception object that was |
10087 // thrown. | 9642 // thrown. |
(...skipping 10 matching lines...) Expand all Loading... |
10098 void Parser::SetupExceptionVariables(LocalScope* try_scope, | 9653 void Parser::SetupExceptionVariables(LocalScope* try_scope, |
10099 bool is_async, | 9654 bool is_async, |
10100 LocalVariable** context_var, | 9655 LocalVariable** context_var, |
10101 LocalVariable** exception_var, | 9656 LocalVariable** exception_var, |
10102 LocalVariable** stack_trace_var, | 9657 LocalVariable** stack_trace_var, |
10103 LocalVariable** saved_exception_var, | 9658 LocalVariable** saved_exception_var, |
10104 LocalVariable** saved_stack_trace_var) { | 9659 LocalVariable** saved_stack_trace_var) { |
10105 // Consecutive try statements share the same set of variables. | 9660 // Consecutive try statements share the same set of variables. |
10106 *context_var = try_scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 9661 *context_var = try_scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
10107 if (*context_var == NULL) { | 9662 if (*context_var == NULL) { |
10108 *context_var = new(Z) LocalVariable( | 9663 *context_var = new (Z) |
10109 TokenPos(), | 9664 LocalVariable(TokenPos(), TokenPos(), Symbols::SavedTryContextVar(), |
10110 TokenPos(), | 9665 Object::dynamic_type()); |
10111 Symbols::SavedTryContextVar(), | |
10112 Object::dynamic_type()); | |
10113 try_scope->AddVariable(*context_var); | 9666 try_scope->AddVariable(*context_var); |
10114 } | 9667 } |
10115 *exception_var = try_scope->LocalLookupVariable(Symbols::ExceptionVar()); | 9668 *exception_var = try_scope->LocalLookupVariable(Symbols::ExceptionVar()); |
10116 if (*exception_var == NULL) { | 9669 if (*exception_var == NULL) { |
10117 *exception_var = new(Z) LocalVariable( | 9670 *exception_var = |
10118 TokenPos(), | 9671 new (Z) LocalVariable(TokenPos(), TokenPos(), Symbols::ExceptionVar(), |
10119 TokenPos(), | 9672 Object::dynamic_type()); |
10120 Symbols::ExceptionVar(), | |
10121 Object::dynamic_type()); | |
10122 try_scope->AddVariable(*exception_var); | 9673 try_scope->AddVariable(*exception_var); |
10123 } | 9674 } |
10124 *stack_trace_var = try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 9675 *stack_trace_var = try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
10125 if (*stack_trace_var == NULL) { | 9676 if (*stack_trace_var == NULL) { |
10126 *stack_trace_var = new(Z) LocalVariable( | 9677 *stack_trace_var = |
10127 TokenPos(), | 9678 new (Z) LocalVariable(TokenPos(), TokenPos(), Symbols::StackTraceVar(), |
10128 TokenPos(), | 9679 Object::dynamic_type()); |
10129 Symbols::StackTraceVar(), | |
10130 Object::dynamic_type()); | |
10131 try_scope->AddVariable(*stack_trace_var); | 9680 try_scope->AddVariable(*stack_trace_var); |
10132 } | 9681 } |
10133 if (is_async) { | 9682 if (is_async) { |
10134 *saved_exception_var = try_scope->LocalLookupVariable( | 9683 *saved_exception_var = |
10135 Symbols::SavedExceptionVar()); | 9684 try_scope->LocalLookupVariable(Symbols::SavedExceptionVar()); |
10136 if (*saved_exception_var == NULL) { | 9685 if (*saved_exception_var == NULL) { |
10137 *saved_exception_var = new(Z) LocalVariable( | 9686 *saved_exception_var = new (Z) |
10138 TokenPos(), | 9687 LocalVariable(TokenPos(), TokenPos(), Symbols::SavedExceptionVar(), |
10139 TokenPos(), | 9688 Object::dynamic_type()); |
10140 Symbols::SavedExceptionVar(), | |
10141 Object::dynamic_type()); | |
10142 try_scope->AddVariable(*saved_exception_var); | 9689 try_scope->AddVariable(*saved_exception_var); |
10143 } | 9690 } |
10144 *saved_stack_trace_var = try_scope->LocalLookupVariable( | 9691 *saved_stack_trace_var = |
10145 Symbols::SavedStackTraceVar()); | 9692 try_scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); |
10146 if (*saved_stack_trace_var == NULL) { | 9693 if (*saved_stack_trace_var == NULL) { |
10147 *saved_stack_trace_var = new(Z) LocalVariable( | 9694 *saved_stack_trace_var = new (Z) |
10148 TokenPos(), | 9695 LocalVariable(TokenPos(), TokenPos(), Symbols::SavedStackTraceVar(), |
10149 TokenPos(), | 9696 Object::dynamic_type()); |
10150 Symbols::SavedStackTraceVar(), | |
10151 Object::dynamic_type()); | |
10152 try_scope->AddVariable(*saved_stack_trace_var); | 9697 try_scope->AddVariable(*saved_stack_trace_var); |
10153 } | 9698 } |
10154 } | 9699 } |
10155 } | 9700 } |
10156 | 9701 |
10157 | 9702 |
10158 AstNode* Parser::ParseTryStatement(String* label_name) { | 9703 AstNode* Parser::ParseTryStatement(String* label_name) { |
10159 TRACE_PARSER("ParseTryStatement"); | 9704 TRACE_PARSER("ParseTryStatement"); |
10160 | 9705 |
10161 const TokenPosition try_pos = TokenPos(); | 9706 const TokenPosition try_pos = TokenPos(); |
10162 SourceLabel* try_label = NULL; | 9707 SourceLabel* try_label = NULL; |
10163 if (label_name != NULL) { | 9708 if (label_name != NULL) { |
10164 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 9709 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
10165 OpenBlock(); | 9710 OpenBlock(); |
10166 current_block_->scope->AddLabel(try_label); | 9711 current_block_->scope->AddLabel(try_label); |
10167 } | 9712 } |
10168 | 9713 |
10169 const bool is_async = innermost_function().IsAsyncClosure() || | 9714 const bool is_async = innermost_function().IsAsyncClosure() || |
10170 innermost_function().IsAsyncFunction() || | 9715 innermost_function().IsAsyncFunction() || |
10171 innermost_function().IsSyncGenClosure() || | 9716 innermost_function().IsSyncGenClosure() || |
10172 innermost_function().IsSyncGenerator() || | 9717 innermost_function().IsSyncGenerator() || |
10173 innermost_function().IsAsyncGenClosure() || | 9718 innermost_function().IsAsyncGenClosure() || |
10174 innermost_function().IsAsyncGenerator(); | 9719 innermost_function().IsAsyncGenerator(); |
10175 LocalVariable* context_var = NULL; | 9720 LocalVariable* context_var = NULL; |
10176 LocalVariable* exception_var = NULL; | 9721 LocalVariable* exception_var = NULL; |
10177 LocalVariable* stack_trace_var = NULL; | 9722 LocalVariable* stack_trace_var = NULL; |
10178 LocalVariable* saved_exception_var = NULL; | 9723 LocalVariable* saved_exception_var = NULL; |
10179 LocalVariable* saved_stack_trace_var = NULL; | 9724 LocalVariable* saved_stack_trace_var = NULL; |
10180 SetupExceptionVariables(current_block_->scope, | 9725 SetupExceptionVariables(current_block_->scope, is_async, &context_var, |
10181 is_async, | 9726 &exception_var, &stack_trace_var, |
10182 &context_var, | 9727 &saved_exception_var, &saved_stack_trace_var); |
10183 &exception_var, | |
10184 &stack_trace_var, | |
10185 &saved_exception_var, | |
10186 &saved_stack_trace_var); | |
10187 | 9728 |
10188 ConsumeToken(); // Consume the 'try'. | 9729 ConsumeToken(); // Consume the 'try'. |
10189 | 9730 |
10190 // Now parse the 'try' block. | 9731 // Now parse the 'try' block. |
10191 OpenBlock(); | 9732 OpenBlock(); |
10192 PushTry(current_block_); | 9733 PushTry(current_block_); |
10193 ExpectToken(Token::kLBRACE); | 9734 ExpectToken(Token::kLBRACE); |
10194 | 9735 |
10195 if (is_async) { | 9736 if (is_async) { |
10196 SetupSavedTryContext(context_var); | 9737 SetupSavedTryContext(context_var); |
10197 } | 9738 } |
10198 | 9739 |
10199 ParseStatementSequence(); | 9740 ParseStatementSequence(); |
10200 ExpectToken(Token::kRBRACE); | 9741 ExpectToken(Token::kRBRACE); |
10201 SequenceNode* try_block = CloseBlock(); | 9742 SequenceNode* try_block = CloseBlock(); |
10202 | 9743 |
10203 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && | 9744 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && |
10204 (CurrentToken() != Token::kFINALLY)) { | 9745 (CurrentToken() != Token::kFINALLY)) { |
10205 ReportError("catch or finally clause expected"); | 9746 ReportError("catch or finally clause expected"); |
10206 } | 9747 } |
10207 | 9748 |
10208 // Now parse the 'catch' blocks if any. | 9749 // Now parse the 'catch' blocks if any. |
10209 try_stack_->enter_catch(); | 9750 try_stack_->enter_catch(); |
10210 const TokenPosition handler_pos = TokenPos(); | 9751 const TokenPosition handler_pos = TokenPos(); |
10211 const GrowableObjectArray& handler_types = | 9752 const GrowableObjectArray& handler_types = |
10212 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 9753 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
10213 bool needs_stack_trace = false; | 9754 bool needs_stack_trace = false; |
10214 SequenceNode* catch_handler_list = | 9755 SequenceNode* catch_handler_list = |
10215 ParseCatchClauses(handler_pos, | 9756 ParseCatchClauses(handler_pos, is_async, exception_var, stack_trace_var, |
10216 is_async, | |
10217 exception_var, | |
10218 stack_trace_var, | |
10219 is_async ? saved_exception_var : exception_var, | 9757 is_async ? saved_exception_var : exception_var, |
10220 is_async ? saved_stack_trace_var : stack_trace_var, | 9758 is_async ? saved_stack_trace_var : stack_trace_var, |
10221 handler_types, | 9759 handler_types, &needs_stack_trace); |
10222 &needs_stack_trace); | |
10223 | 9760 |
10224 TryStack* try_statement = PopTry(); | 9761 TryStack* try_statement = PopTry(); |
10225 const intptr_t try_index = try_statement->try_index(); | 9762 const intptr_t try_index = try_statement->try_index(); |
10226 TryStack* outer_try = try_stack_; | 9763 TryStack* outer_try = try_stack_; |
10227 const intptr_t outer_try_index = (outer_try != NULL) ? | 9764 const intptr_t outer_try_index = (outer_try != NULL) |
10228 outer_try->try_index() : CatchClauseNode::kInvalidTryIndex; | 9765 ? outer_try->try_index() |
| 9766 : CatchClauseNode::kInvalidTryIndex; |
10229 | 9767 |
10230 // Finally, parse or generate the 'finally' clause. | 9768 // Finally, parse or generate the 'finally' clause. |
10231 // A finally clause is required in async code to restore the saved try context | 9769 // A finally clause is required in async code to restore the saved try context |
10232 // of an existing outer try. Generate a finally clause to this purpose if it | 9770 // of an existing outer try. Generate a finally clause to this purpose if it |
10233 // is not declared. | 9771 // is not declared. |
10234 SequenceNode* finally_clause = NULL; | 9772 SequenceNode* finally_clause = NULL; |
10235 SequenceNode* rethrow_clause = NULL; | 9773 SequenceNode* rethrow_clause = NULL; |
10236 const bool parse = CurrentToken() == Token::kFINALLY; | 9774 const bool parse = CurrentToken() == Token::kFINALLY; |
10237 if (parse || (is_async && (try_stack_ != NULL))) { | 9775 if (parse || (is_async && (try_stack_ != NULL))) { |
10238 if (parse) { | 9776 if (parse) { |
10239 ConsumeToken(); // Consume the 'finally'. | 9777 ConsumeToken(); // Consume the 'finally'. |
10240 } | 9778 } |
10241 const TokenPosition finally_pos = TokenPos(); | 9779 const TokenPosition finally_pos = TokenPos(); |
10242 // Add the finally block to the exit points recorded so far. | 9780 // Add the finally block to the exit points recorded so far. |
10243 intptr_t node_index = 0; | 9781 intptr_t node_index = 0; |
10244 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 9782 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
10245 while (node_to_inline != NULL) { | 9783 while (node_to_inline != NULL) { |
10246 finally_clause = EnsureFinallyClause( | 9784 finally_clause = EnsureFinallyClause( |
10247 parse, | 9785 parse, is_async, exception_var, stack_trace_var, |
10248 is_async, | |
10249 exception_var, | |
10250 stack_trace_var, | |
10251 is_async ? saved_exception_var : exception_var, | 9786 is_async ? saved_exception_var : exception_var, |
10252 is_async ? saved_stack_trace_var : stack_trace_var); | 9787 is_async ? saved_stack_trace_var : stack_trace_var); |
10253 InlinedFinallyNode* node = new(Z) InlinedFinallyNode(finally_pos, | 9788 InlinedFinallyNode* node = new (Z) InlinedFinallyNode( |
10254 finally_clause, | 9789 finally_pos, finally_clause, context_var, outer_try_index); |
10255 context_var, | |
10256 outer_try_index); | |
10257 AddFinallyClauseToNode(is_async, node_to_inline, node); | 9790 AddFinallyClauseToNode(is_async, node_to_inline, node); |
10258 node_index += 1; | 9791 node_index += 1; |
10259 node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 9792 node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
10260 tokens_iterator_.SetCurrentPosition(finally_pos); | 9793 tokens_iterator_.SetCurrentPosition(finally_pos); |
10261 } | 9794 } |
10262 finally_clause = EnsureFinallyClause( | 9795 finally_clause = |
10263 parse, | 9796 EnsureFinallyClause(parse, is_async, exception_var, stack_trace_var, |
10264 is_async, | 9797 is_async ? saved_exception_var : exception_var, |
10265 exception_var, | 9798 is_async ? saved_stack_trace_var : stack_trace_var); |
10266 stack_trace_var, | |
10267 is_async ? saved_exception_var : exception_var, | |
10268 is_async ? saved_stack_trace_var : stack_trace_var); | |
10269 if (finally_clause != NULL) { | 9799 if (finally_clause != NULL) { |
10270 // Re-parse to create a duplicate of finally clause to avoid unintended | 9800 // Re-parse to create a duplicate of finally clause to avoid unintended |
10271 // sharing of try-indices if the finally-block contains a try-catch. | 9801 // sharing of try-indices if the finally-block contains a try-catch. |
10272 // The flow graph builder emits two copies of the finally-block if the | 9802 // The flow graph builder emits two copies of the finally-block if the |
10273 // try-block has a normal exit: one for the exception- and one for the | 9803 // try-block has a normal exit: one for the exception- and one for the |
10274 // non-exception case (see EffectGraphVisitor::VisitTryCatchNode) | 9804 // non-exception case (see EffectGraphVisitor::VisitTryCatchNode) |
10275 tokens_iterator_.SetCurrentPosition(finally_pos); | 9805 tokens_iterator_.SetCurrentPosition(finally_pos); |
10276 rethrow_clause = EnsureFinallyClause( | 9806 rethrow_clause = EnsureFinallyClause( |
10277 parse, | 9807 parse, is_async, exception_var, stack_trace_var, |
10278 is_async, | |
10279 exception_var, | |
10280 stack_trace_var, | |
10281 is_async ? saved_exception_var : exception_var, | 9808 is_async ? saved_exception_var : exception_var, |
10282 is_async ? saved_stack_trace_var : stack_trace_var); | 9809 is_async ? saved_stack_trace_var : stack_trace_var); |
10283 } | 9810 } |
10284 } | 9811 } |
10285 | 9812 |
10286 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 9813 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
10287 handler_pos, | 9814 handler_pos, catch_handler_list, |
10288 catch_handler_list, | 9815 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), context_var, |
10289 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 9816 exception_var, stack_trace_var, |
10290 context_var, | |
10291 exception_var, | |
10292 stack_trace_var, | |
10293 is_async ? saved_exception_var : exception_var, | 9817 is_async ? saved_exception_var : exception_var, |
10294 is_async ? saved_stack_trace_var : stack_trace_var, | 9818 is_async ? saved_stack_trace_var : stack_trace_var, |
10295 (finally_clause != NULL) ? | 9819 (finally_clause != NULL) ? AllocateTryIndex() |
10296 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, | 9820 : CatchClauseNode::kInvalidTryIndex, |
10297 needs_stack_trace); | 9821 needs_stack_trace); |
10298 | 9822 |
10299 // Now create the try/catch ast node and return it. If there is a label | 9823 // Now create the try/catch ast node and return it. If there is a label |
10300 // on the try/catch, close the block that's embedding the try statement | 9824 // on the try/catch, close the block that's embedding the try statement |
10301 // and attach the label to it. | 9825 // and attach the label to it. |
10302 AstNode* try_catch_node = new(Z) TryCatchNode( | 9826 AstNode* try_catch_node = |
10303 try_pos, try_block, context_var, catch_clause, finally_clause, try_index, | 9827 new (Z) TryCatchNode(try_pos, try_block, context_var, catch_clause, |
10304 rethrow_clause); | 9828 finally_clause, try_index, rethrow_clause); |
10305 | 9829 |
10306 if (try_label != NULL) { | 9830 if (try_label != NULL) { |
10307 current_block_->statements->Add(try_catch_node); | 9831 current_block_->statements->Add(try_catch_node); |
10308 SequenceNode* sequence = CloseBlock(); | 9832 SequenceNode* sequence = CloseBlock(); |
10309 sequence->set_label(try_label); | 9833 sequence->set_label(try_label); |
10310 try_catch_node = sequence; | 9834 try_catch_node = sequence; |
10311 } | 9835 } |
10312 | 9836 |
10313 return try_catch_node; | 9837 return try_catch_node; |
10314 } | 9838 } |
(...skipping 21 matching lines...) Expand all Loading... |
10336 } | 9860 } |
10337 target = current_block_->scope->LookupLabel(target_name); | 9861 target = current_block_->scope->LookupLabel(target_name); |
10338 if (target == NULL && jump_kind == Token::kCONTINUE) { | 9862 if (target == NULL && jump_kind == Token::kCONTINUE) { |
10339 // Either a reference to a non-existent label, or a forward reference | 9863 // Either a reference to a non-existent label, or a forward reference |
10340 // to a case label that we haven't seen yet. If we are inside a switch | 9864 // to a case label that we haven't seen yet. If we are inside a switch |
10341 // statement, create a "forward reference" label in the scope of | 9865 // statement, create a "forward reference" label in the scope of |
10342 // the switch statement. | 9866 // the switch statement. |
10343 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); | 9867 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); |
10344 if (switch_scope != NULL) { | 9868 if (switch_scope != NULL) { |
10345 // We found a switch scope. Enter a forward reference to the label. | 9869 // We found a switch scope. Enter a forward reference to the label. |
10346 target = new(Z) SourceLabel( | 9870 target = |
10347 TokenPos(), target_name, SourceLabel::kForward); | 9871 new (Z) SourceLabel(TokenPos(), target_name, SourceLabel::kForward); |
10348 switch_scope->AddLabel(target); | 9872 switch_scope->AddLabel(target); |
10349 } | 9873 } |
10350 } | 9874 } |
10351 if (target == NULL) { | 9875 if (target == NULL) { |
10352 ReportError(jump_pos, "label '%s' not found", target_name.ToCString()); | 9876 ReportError(jump_pos, "label '%s' not found", target_name.ToCString()); |
10353 } | 9877 } |
10354 } else if (FLAG_enable_debug_break && (CurrentToken() == Token::kSTRING)) { | 9878 } else if (FLAG_enable_debug_break && (CurrentToken() == Token::kSTRING)) { |
10355 const char* message = strdup(CurrentLiteral()->ToCString()); | 9879 const char* message = strdup(CurrentLiteral()->ToCString()); |
10356 ConsumeToken(); | 9880 ConsumeToken(); |
10357 return new(Z) StopNode(jump_pos, message); | 9881 return new (Z) StopNode(jump_pos, message); |
10358 } else { | 9882 } else { |
10359 target = current_block_->scope->LookupInnermostLabel(jump_kind); | 9883 target = current_block_->scope->LookupInnermostLabel(jump_kind); |
10360 if (target == NULL) { | 9884 if (target == NULL) { |
10361 ReportError(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); | 9885 ReportError(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); |
10362 } | 9886 } |
10363 } | 9887 } |
10364 ASSERT(target != NULL); | 9888 ASSERT(target != NULL); |
10365 if (jump_kind == Token::kCONTINUE) { | 9889 if (jump_kind == Token::kCONTINUE) { |
10366 if (target->kind() == SourceLabel::kSwitch) { | 9890 if (target->kind() == SourceLabel::kSwitch) { |
10367 ReportError(jump_pos, "'continue' jump to switch statement is illegal"); | 9891 ReportError(jump_pos, "'continue' jump to switch statement is illegal"); |
10368 } else if (target->kind() == SourceLabel::kStatement) { | 9892 } else if (target->kind() == SourceLabel::kStatement) { |
10369 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", | 9893 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", |
10370 target->name().ToCString()); | 9894 target->name().ToCString()); |
10371 } | 9895 } |
10372 } | 9896 } |
10373 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { | 9897 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { |
10374 ReportError(jump_pos, "'break' to case clause label is illegal"); | 9898 ReportError(jump_pos, "'break' to case clause label is illegal"); |
10375 } | 9899 } |
10376 if (target->FunctionLevel() != FunctionLevel()) { | 9900 if (target->FunctionLevel() != FunctionLevel()) { |
10377 ReportError(jump_pos, "'%s' target must be in same function context", | 9901 ReportError(jump_pos, "'%s' target must be in same function context", |
10378 Token::Str(jump_kind)); | 9902 Token::Str(jump_kind)); |
10379 } | 9903 } |
10380 return new(Z) JumpNode(jump_pos, jump_kind, target); | 9904 return new (Z) JumpNode(jump_pos, jump_kind, target); |
10381 } | 9905 } |
10382 | 9906 |
10383 | 9907 |
10384 AstNode* Parser::ParseYieldStatement() { | 9908 AstNode* Parser::ParseYieldStatement() { |
10385 bool is_yield_each = false; | 9909 bool is_yield_each = false; |
10386 const TokenPosition yield_pos = TokenPos(); | 9910 const TokenPosition yield_pos = TokenPos(); |
10387 ConsumeToken(); // yield reserved word. | 9911 ConsumeToken(); // yield reserved word. |
10388 if (CurrentToken() == Token::kMUL) { | 9912 if (CurrentToken() == Token::kMUL) { |
10389 is_yield_each = true; | 9913 is_yield_each = true; |
10390 ConsumeToken(); | 9914 ConsumeToken(); |
10391 } | 9915 } |
10392 if (!innermost_function().IsGenerator() && | 9916 if (!innermost_function().IsGenerator() && |
10393 !innermost_function().IsGeneratorClosure()) { | 9917 !innermost_function().IsGeneratorClosure()) { |
10394 ReportError(yield_pos, | 9918 ReportError(yield_pos, |
10395 "yield%s statement only allowed in generator functions", | 9919 "yield%s statement only allowed in generator functions", |
10396 is_yield_each ? "*" : ""); | 9920 is_yield_each ? "*" : ""); |
10397 } | 9921 } |
10398 | 9922 |
10399 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9923 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
10400 | 9924 |
10401 LetNode* yield = new(Z) LetNode(yield_pos); | 9925 LetNode* yield = new (Z) LetNode(yield_pos); |
10402 if (innermost_function().IsSyncGenerator() || | 9926 if (innermost_function().IsSyncGenerator() || |
10403 innermost_function().IsSyncGenClosure()) { | 9927 innermost_function().IsSyncGenClosure()) { |
10404 // Yield statement in sync* function. | 9928 // Yield statement in sync* function. |
10405 | 9929 |
10406 LocalVariable* iterator_param = | 9930 LocalVariable* iterator_param = |
10407 LookupLocalScope(Symbols::IteratorParameter()); | 9931 LookupLocalScope(Symbols::IteratorParameter()); |
10408 ASSERT(iterator_param != NULL); | 9932 ASSERT(iterator_param != NULL); |
10409 // Generate :iterator.current = expr; | 9933 // Generate :iterator.current = expr; |
10410 AstNode* iterator = | 9934 AstNode* iterator = |
10411 new(Z) LoadLocalNode(TokenPosition::kNoSource, iterator_param); | 9935 new (Z) LoadLocalNode(TokenPosition::kNoSource, iterator_param); |
10412 AstNode* store_current = | 9936 AstNode* store_current = new (Z) InstanceSetterNode( |
10413 new(Z) InstanceSetterNode(TokenPosition::kNoSource, | 9937 TokenPosition::kNoSource, iterator, |
10414 iterator, | 9938 Library::PrivateCoreLibName(Symbols::_current()), expr); |
10415 Library::PrivateCoreLibName( | |
10416 Symbols::_current()), | |
10417 expr); | |
10418 yield->AddNode(store_current); | 9939 yield->AddNode(store_current); |
10419 if (is_yield_each) { | 9940 if (is_yield_each) { |
10420 // Generate :iterator.isYieldEach = true; | 9941 // Generate :iterator.isYieldEach = true; |
10421 AstNode* set_is_yield_each = | 9942 AstNode* set_is_yield_each = new (Z) |
10422 new(Z) InstanceSetterNode(TokenPosition::kNoSource, | 9943 InstanceSetterNode(TokenPosition::kNoSource, iterator, |
10423 iterator, | 9944 String::ZoneHandle(Symbols::IsYieldEach().raw()), |
10424 String::ZoneHandle(Symbols::IsYieldEach().raw()), | 9945 new (Z) LiteralNode(TokenPos(), Bool::True())); |
10425 new(Z) LiteralNode(TokenPos(), Bool::True())); | |
10426 yield->AddNode(set_is_yield_each); | 9946 yield->AddNode(set_is_yield_each); |
10427 } | 9947 } |
10428 AwaitMarkerNode* await_marker = | 9948 AwaitMarkerNode* await_marker = new (Z) AwaitMarkerNode( |
10429 new(Z) AwaitMarkerNode(async_temp_scope_, | 9949 async_temp_scope_, current_block_->scope, TokenPosition::kNoSource); |
10430 current_block_->scope, | |
10431 TokenPosition::kNoSource); | |
10432 yield->AddNode(await_marker); | 9950 yield->AddNode(await_marker); |
10433 // Return true to indicate that a value has been generated. | 9951 // Return true to indicate that a value has been generated. |
10434 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, | 9952 ReturnNode* return_true = new (Z) |
10435 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9953 ReturnNode(yield_pos, new (Z) LiteralNode(TokenPos(), Bool::True())); |
10436 return_true->set_return_type(ReturnNode::kContinuationTarget); | 9954 return_true->set_return_type(ReturnNode::kContinuationTarget); |
10437 yield->AddNode(return_true); | 9955 yield->AddNode(return_true); |
10438 | 9956 |
10439 // If this expression is part of a try block, also append the code for | 9957 // If this expression is part of a try block, also append the code for |
10440 // restoring the saved try context that lives on the stack and possibly the | 9958 // restoring the saved try context that lives on the stack and possibly the |
10441 // saved try context of the outer try block. | 9959 // saved try context of the outer try block. |
10442 LocalVariable* saved_try_ctx; | 9960 LocalVariable* saved_try_ctx; |
10443 LocalVariable* async_saved_try_ctx; | 9961 LocalVariable* async_saved_try_ctx; |
10444 LocalVariable* outer_saved_try_ctx; | 9962 LocalVariable* outer_saved_try_ctx; |
10445 LocalVariable* outer_async_saved_try_ctx; | 9963 LocalVariable* outer_async_saved_try_ctx; |
10446 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9964 CheckAsyncOpInTryBlock(&saved_try_ctx, &async_saved_try_ctx, |
10447 &async_saved_try_ctx, | 9965 &outer_saved_try_ctx, &outer_async_saved_try_ctx); |
10448 &outer_saved_try_ctx, | |
10449 &outer_async_saved_try_ctx); | |
10450 if (saved_try_ctx != NULL) { | 9966 if (saved_try_ctx != NULL) { |
10451 yield->AddNode(new (Z) StoreLocalNode( | 9967 yield->AddNode(new (Z) StoreLocalNode( |
10452 TokenPosition::kNoSource, | 9968 TokenPosition::kNoSource, saved_try_ctx, |
10453 saved_try_ctx, | 9969 new (Z) |
10454 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 9970 LoadLocalNode(TokenPosition::kNoSource, async_saved_try_ctx))); |
10455 async_saved_try_ctx))); | |
10456 if (outer_saved_try_ctx != NULL) { | 9971 if (outer_saved_try_ctx != NULL) { |
10457 yield->AddNode(new (Z) StoreLocalNode( | 9972 yield->AddNode(new (Z) StoreLocalNode( |
10458 TokenPosition::kNoSource, | 9973 TokenPosition::kNoSource, outer_saved_try_ctx, |
10459 outer_saved_try_ctx, | |
10460 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 9974 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
10461 outer_async_saved_try_ctx))); | 9975 outer_async_saved_try_ctx))); |
10462 } | 9976 } |
10463 } else { | 9977 } else { |
10464 ASSERT(outer_saved_try_ctx == NULL); | 9978 ASSERT(outer_saved_try_ctx == NULL); |
10465 } | 9979 } |
10466 } else { | 9980 } else { |
10467 // yield statement in async* function. | 9981 // yield statement in async* function. |
10468 ASSERT(innermost_function().IsAsyncGenerator() || | 9982 ASSERT(innermost_function().IsAsyncGenerator() || |
10469 innermost_function().IsAsyncGenClosure()); | 9983 innermost_function().IsAsyncGenClosure()); |
10470 | 9984 |
10471 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); | 9985 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); |
10472 ASSERT(controller_var != NULL); | 9986 ASSERT(controller_var != NULL); |
10473 // :controller.add[Stream](expr); | 9987 // :controller.add[Stream](expr); |
10474 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); | 9988 ArgumentListNode* add_args = new (Z) ArgumentListNode(yield_pos); |
10475 add_args->Add(expr); | 9989 add_args->Add(expr); |
10476 AstNode* add_call = | 9990 AstNode* add_call = new (Z) InstanceCallNode( |
10477 new(Z) InstanceCallNode(yield_pos, | 9991 yield_pos, |
10478 new(Z) LoadLocalNode(TokenPosition::kNoSource, controller_var), | 9992 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var), |
10479 is_yield_each ? Symbols::AddStream() : Symbols::add(), | 9993 is_yield_each ? Symbols::AddStream() : Symbols::add(), add_args); |
10480 add_args); | |
10481 | 9994 |
10482 // if (:controller.add[Stream](expr)) { | 9995 // if (:controller.add[Stream](expr)) { |
10483 // return; | 9996 // return; |
10484 // } | 9997 // } |
10485 // await_marker; | 9998 // await_marker; |
10486 // continuation_return; | 9999 // continuation_return; |
10487 // restore saved_try_context | 10000 // restore saved_try_context |
10488 | 10001 |
10489 SequenceNode* true_branch = | 10002 SequenceNode* true_branch = |
10490 new(Z) SequenceNode(TokenPosition::kNoSource, NULL); | 10003 new (Z) SequenceNode(TokenPosition::kNoSource, NULL); |
10491 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); | 10004 AstNode* return_from_generator = new (Z) ReturnNode(yield_pos); |
10492 true_branch->Add(return_from_generator); | 10005 true_branch->Add(return_from_generator); |
10493 AddNodeForFinallyInlining(return_from_generator); | 10006 AddNodeForFinallyInlining(return_from_generator); |
10494 AstNode* if_is_cancelled = | 10007 AstNode* if_is_cancelled = |
10495 new(Z) IfNode(TokenPosition::kNoSource, add_call, true_branch, NULL); | 10008 new (Z) IfNode(TokenPosition::kNoSource, add_call, true_branch, NULL); |
10496 yield->AddNode(if_is_cancelled); | 10009 yield->AddNode(if_is_cancelled); |
10497 | 10010 |
10498 AwaitMarkerNode* await_marker = | 10011 AwaitMarkerNode* await_marker = new (Z) AwaitMarkerNode( |
10499 new(Z) AwaitMarkerNode(async_temp_scope_, | 10012 async_temp_scope_, current_block_->scope, TokenPosition::kNoSource); |
10500 current_block_->scope, | |
10501 TokenPosition::kNoSource); | |
10502 yield->AddNode(await_marker); | 10013 yield->AddNode(await_marker); |
10503 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); | 10014 ReturnNode* continuation_return = new (Z) ReturnNode(yield_pos); |
10504 continuation_return->set_return_type(ReturnNode::kContinuationTarget); | 10015 continuation_return->set_return_type(ReturnNode::kContinuationTarget); |
10505 yield->AddNode(continuation_return); | 10016 yield->AddNode(continuation_return); |
10506 | 10017 |
10507 // If this expression is part of a try block, also append the code for | 10018 // If this expression is part of a try block, also append the code for |
10508 // restoring the saved try context that lives on the stack and possibly the | 10019 // restoring the saved try context that lives on the stack and possibly the |
10509 // saved try context of the outer try block. | 10020 // saved try context of the outer try block. |
10510 LocalVariable* saved_try_ctx; | 10021 LocalVariable* saved_try_ctx; |
10511 LocalVariable* async_saved_try_ctx; | 10022 LocalVariable* async_saved_try_ctx; |
10512 LocalVariable* outer_saved_try_ctx; | 10023 LocalVariable* outer_saved_try_ctx; |
10513 LocalVariable* outer_async_saved_try_ctx; | 10024 LocalVariable* outer_async_saved_try_ctx; |
10514 CheckAsyncOpInTryBlock(&saved_try_ctx, | 10025 CheckAsyncOpInTryBlock(&saved_try_ctx, &async_saved_try_ctx, |
10515 &async_saved_try_ctx, | 10026 &outer_saved_try_ctx, &outer_async_saved_try_ctx); |
10516 &outer_saved_try_ctx, | |
10517 &outer_async_saved_try_ctx); | |
10518 if (saved_try_ctx != NULL) { | 10027 if (saved_try_ctx != NULL) { |
10519 yield->AddNode(new (Z) StoreLocalNode( | 10028 yield->AddNode(new (Z) StoreLocalNode( |
10520 TokenPosition::kNoSource, | 10029 TokenPosition::kNoSource, saved_try_ctx, |
10521 saved_try_ctx, | 10030 new (Z) |
10522 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 10031 LoadLocalNode(TokenPosition::kNoSource, async_saved_try_ctx))); |
10523 async_saved_try_ctx))); | |
10524 if (outer_saved_try_ctx != NULL) { | 10032 if (outer_saved_try_ctx != NULL) { |
10525 yield->AddNode(new (Z) StoreLocalNode( | 10033 yield->AddNode(new (Z) StoreLocalNode( |
10526 TokenPosition::kNoSource, | 10034 TokenPosition::kNoSource, outer_saved_try_ctx, |
10527 outer_saved_try_ctx, | |
10528 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 10035 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
10529 outer_async_saved_try_ctx))); | 10036 outer_async_saved_try_ctx))); |
10530 } | 10037 } |
10531 } else { | 10038 } else { |
10532 ASSERT(outer_saved_try_ctx == NULL); | 10039 ASSERT(outer_saved_try_ctx == NULL); |
10533 } | 10040 } |
10534 } | 10041 } |
10535 return yield; | 10042 return yield; |
10536 } | 10043 } |
10537 | 10044 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10570 const TokenPosition return_pos = TokenPos(); | 10077 const TokenPosition return_pos = TokenPos(); |
10571 ConsumeToken(); | 10078 ConsumeToken(); |
10572 if (CurrentToken() != Token::kSEMICOLON) { | 10079 if (CurrentToken() != Token::kSEMICOLON) { |
10573 const TokenPosition expr_pos = TokenPos(); | 10080 const TokenPosition expr_pos = TokenPos(); |
10574 const int function_level = FunctionLevel(); | 10081 const int function_level = FunctionLevel(); |
10575 if (current_function().IsGenerativeConstructor() && | 10082 if (current_function().IsGenerativeConstructor() && |
10576 (function_level == 0)) { | 10083 (function_level == 0)) { |
10577 ReportError(expr_pos, | 10084 ReportError(expr_pos, |
10578 "return of a value is not allowed in constructors"); | 10085 "return of a value is not allowed in constructors"); |
10579 } else if (current_function().IsGeneratorClosure() && | 10086 } else if (current_function().IsGeneratorClosure() && |
10580 (function_level == 0)) { | 10087 (function_level == 0)) { |
10581 ReportError(expr_pos, "generator functions may not return a value"); | 10088 ReportError(expr_pos, "generator functions may not return a value"); |
10582 } | 10089 } |
10583 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 10090 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
10584 if (I->type_checks() && | 10091 if (I->type_checks() && |
10585 (((function_level == 0) && current_function().IsAsyncClosure()))) { | 10092 (((function_level == 0) && current_function().IsAsyncClosure()))) { |
10586 // In checked mode, when the declared result type is Future<T>, verify | 10093 // In checked mode, when the declared result type is Future<T>, verify |
10587 // that the returned expression is of type T or Future<T> as follows: | 10094 // that the returned expression is of type T or Future<T> as follows: |
10588 // return temp = expr, temp is Future ? temp as Future<T> : temp as T; | 10095 // return temp = expr, temp is Future ? temp as Future<T> : temp as T; |
10589 // In case of a mismatch, we need a TypeError and not a CastError, so | 10096 // In case of a mismatch, we need a TypeError and not a CastError, so |
10590 // we do not actually implement an "as" test, but an "assignable" test. | 10097 // we do not actually implement an "as" test, but an "assignable" test. |
10591 Function& async_func = | 10098 Function& async_func = |
10592 Function::Handle(Z, current_function().parent_function()); | 10099 Function::Handle(Z, current_function().parent_function()); |
10593 const AbstractType& result_type = | 10100 const AbstractType& result_type = |
10594 AbstractType::ZoneHandle(Z, async_func.result_type()); | 10101 AbstractType::ZoneHandle(Z, async_func.result_type()); |
10595 const Class& future_class = | 10102 const Class& future_class = |
10596 Class::ZoneHandle(Z, I->object_store()->future_class()); | 10103 Class::ZoneHandle(Z, I->object_store()->future_class()); |
10597 ASSERT(!future_class.IsNull()); | 10104 ASSERT(!future_class.IsNull()); |
10598 if (result_type.type_class() == future_class.raw()) { | 10105 if (result_type.type_class() == future_class.raw()) { |
10599 const TypeArguments& result_type_args = | 10106 const TypeArguments& result_type_args = |
10600 TypeArguments::ZoneHandle(Z, result_type.arguments()); | 10107 TypeArguments::ZoneHandle(Z, result_type.arguments()); |
10601 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) { | 10108 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) { |
10602 const AbstractType& result_type_arg = | 10109 const AbstractType& result_type_arg = |
10603 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0)); | 10110 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0)); |
10604 LetNode* checked_expr = new(Z) LetNode(expr_pos); | 10111 LetNode* checked_expr = new (Z) LetNode(expr_pos); |
10605 LocalVariable* temp = checked_expr->AddInitializer(expr); | 10112 LocalVariable* temp = checked_expr->AddInitializer(expr); |
10606 temp->set_is_final(); | 10113 temp->set_is_final(); |
10607 const AbstractType& future_type = | 10114 const AbstractType& future_type = |
10608 AbstractType::ZoneHandle(Z, future_class.RareType()); | 10115 AbstractType::ZoneHandle(Z, future_class.RareType()); |
10609 AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp); | 10116 AstNode* is_future = new (Z) LoadLocalNode(expr_pos, temp); |
10610 is_future = new(Z) ComparisonNode(expr_pos, | 10117 is_future = |
10611 Token::kIS, | 10118 new (Z) ComparisonNode(expr_pos, Token::kIS, is_future, |
10612 is_future, | 10119 new (Z) TypeNode(expr_pos, future_type)); |
10613 new(Z) TypeNode(expr_pos, | 10120 AstNode* as_future_t = new (Z) LoadLocalNode(expr_pos, temp); |
10614 future_type)); | 10121 as_future_t = new (Z) AssignableNode( |
10615 AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp); | 10122 expr_pos, as_future_t, result_type, Symbols::FunctionResult()); |
10616 as_future_t = new(Z) AssignableNode(expr_pos, | 10123 AstNode* as_t = new (Z) LoadLocalNode(expr_pos, temp); |
10617 as_future_t, | 10124 as_t = new (Z) AssignableNode(expr_pos, as_t, result_type_arg, |
10618 result_type, | 10125 Symbols::FunctionResult()); |
10619 Symbols::FunctionResult()); | 10126 checked_expr->AddNode(new (Z) ConditionalExprNode( |
10620 AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp); | 10127 expr_pos, is_future, as_future_t, as_t)); |
10621 as_t = new(Z) AssignableNode(expr_pos, | |
10622 as_t, | |
10623 result_type_arg, | |
10624 Symbols::FunctionResult()); | |
10625 checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos, | |
10626 is_future, | |
10627 as_future_t, | |
10628 as_t)); | |
10629 expr = checked_expr; | 10128 expr = checked_expr; |
10630 } | 10129 } |
10631 } | 10130 } |
10632 } | 10131 } |
10633 statement = new(Z) ReturnNode(statement_pos, expr); | 10132 statement = new (Z) ReturnNode(statement_pos, expr); |
10634 } else { | 10133 } else { |
10635 if (current_function().IsSyncGenClosure() && | 10134 if (current_function().IsSyncGenClosure() && (FunctionLevel() == 0)) { |
10636 (FunctionLevel() == 0)) { | |
10637 // In a synchronous generator, return without an expression | 10135 // In a synchronous generator, return without an expression |
10638 // returns false, signaling that the iterator terminates and | 10136 // returns false, signaling that the iterator terminates and |
10639 // did not yield a value. | 10137 // did not yield a value. |
10640 statement = new(Z) ReturnNode(statement_pos, | 10138 statement = new (Z) ReturnNode( |
10641 new(Z) LiteralNode(return_pos, Bool::False())); | 10139 statement_pos, new (Z) LiteralNode(return_pos, Bool::False())); |
10642 } else { | 10140 } else { |
10643 statement = new(Z) ReturnNode(statement_pos); | 10141 statement = new (Z) ReturnNode(statement_pos); |
10644 } | 10142 } |
10645 } | 10143 } |
10646 AddNodeForFinallyInlining(statement); | 10144 AddNodeForFinallyInlining(statement); |
10647 ExpectSemicolon(); | 10145 ExpectSemicolon(); |
10648 } else if (IsYieldKeyword()) { | 10146 } else if (IsYieldKeyword()) { |
10649 statement = ParseYieldStatement(); | 10147 statement = ParseYieldStatement(); |
10650 ExpectSemicolon(); | 10148 ExpectSemicolon(); |
10651 } else if (token == Token::kIF) { | 10149 } else if (token == Token::kIF) { |
10652 statement = ParseIfStatement(label_name); | 10150 statement = ParseIfStatement(label_name); |
10653 } else if (token == Token::kASSERT) { | 10151 } else if (token == Token::kASSERT) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10715 innermost_function().IsAsyncGenerator()) { | 10213 innermost_function().IsAsyncGenerator()) { |
10716 excp_var = scope->LocalLookupVariable(Symbols::SavedExceptionVar()); | 10214 excp_var = scope->LocalLookupVariable(Symbols::SavedExceptionVar()); |
10717 trace_var = scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); | 10215 trace_var = scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); |
10718 } else { | 10216 } else { |
10719 excp_var = scope->LocalLookupVariable(Symbols::ExceptionVar()); | 10217 excp_var = scope->LocalLookupVariable(Symbols::ExceptionVar()); |
10720 trace_var = scope->LocalLookupVariable(Symbols::StackTraceVar()); | 10218 trace_var = scope->LocalLookupVariable(Symbols::StackTraceVar()); |
10721 } | 10219 } |
10722 ASSERT(excp_var != NULL); | 10220 ASSERT(excp_var != NULL); |
10723 ASSERT(trace_var != NULL); | 10221 ASSERT(trace_var != NULL); |
10724 | 10222 |
10725 statement = new(Z) ThrowNode( | 10223 statement = new (Z) |
10726 statement_pos, | 10224 ThrowNode(statement_pos, new (Z) LoadLocalNode(statement_pos, excp_var), |
10727 new(Z) LoadLocalNode(statement_pos, excp_var), | 10225 new (Z) LoadLocalNode(statement_pos, trace_var)); |
10728 new(Z) LoadLocalNode(statement_pos, trace_var)); | |
10729 } else { | 10226 } else { |
10730 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 10227 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
10731 ExpectSemicolon(); | 10228 ExpectSemicolon(); |
10732 } | 10229 } |
10733 return statement; | 10230 return statement; |
10734 } | 10231 } |
10735 | 10232 |
10736 | 10233 |
10737 void Parser::ReportError(const Error& error) { | 10234 void Parser::ReportError(const Error& error) { |
10738 Report::LongJump(error); | 10235 Report::LongJump(error); |
10739 UNREACHABLE(); | 10236 UNREACHABLE(); |
10740 } | 10237 } |
10741 | 10238 |
10742 | 10239 |
10743 void Parser::ReportErrors(const Error& prev_error, | 10240 void Parser::ReportErrors(const Error& prev_error, |
10744 const Script& script, TokenPosition token_pos, | 10241 const Script& script, |
10745 const char* format, ...) { | 10242 TokenPosition token_pos, |
| 10243 const char* format, |
| 10244 ...) { |
10746 va_list args; | 10245 va_list args; |
10747 va_start(args, format); | 10246 va_start(args, format); |
10748 Report::LongJumpV(prev_error, script, token_pos, format, args); | 10247 Report::LongJumpV(prev_error, script, token_pos, format, args); |
10749 va_end(args); | 10248 va_end(args); |
10750 UNREACHABLE(); | 10249 UNREACHABLE(); |
10751 } | 10250 } |
10752 | 10251 |
10753 | 10252 |
10754 void Parser::ReportError(TokenPosition token_pos, | 10253 void Parser::ReportError(TokenPosition token_pos, |
10755 const char* format, ...) const { | 10254 const char* format, |
| 10255 ...) const { |
10756 va_list args; | 10256 va_list args; |
10757 va_start(args, format); | 10257 va_start(args, format); |
10758 Report::MessageV(Report::kError, | 10258 Report::MessageV(Report::kError, script_, token_pos, Report::AtLocation, |
10759 script_, token_pos, Report::AtLocation, format, args); | 10259 format, args); |
10760 va_end(args); | 10260 va_end(args); |
10761 UNREACHABLE(); | 10261 UNREACHABLE(); |
10762 } | 10262 } |
10763 | 10263 |
10764 | 10264 |
10765 void Parser::ReportErrorBefore(const char* format, ...) { | 10265 void Parser::ReportErrorBefore(const char* format, ...) { |
10766 va_list args; | 10266 va_list args; |
10767 va_start(args, format); | 10267 va_start(args, format); |
10768 Report::MessageV(Report::kError, | 10268 Report::MessageV(Report::kError, script_, PrevTokenPos(), |
10769 script_, PrevTokenPos(), Report::AfterLocation, | 10269 Report::AfterLocation, format, args); |
10770 format, args); | |
10771 va_end(args); | 10270 va_end(args); |
10772 UNREACHABLE(); | 10271 UNREACHABLE(); |
10773 } | 10272 } |
10774 | 10273 |
10775 | 10274 |
10776 void Parser::ReportError(const char* format, ...) const { | 10275 void Parser::ReportError(const char* format, ...) const { |
10777 va_list args; | 10276 va_list args; |
10778 va_start(args, format); | 10277 va_start(args, format); |
10779 Report::MessageV(Report::kError, | 10278 Report::MessageV(Report::kError, script_, TokenPos(), Report::AtLocation, |
10780 script_, TokenPos(), Report::AtLocation, format, args); | 10279 format, args); |
10781 va_end(args); | 10280 va_end(args); |
10782 UNREACHABLE(); | 10281 UNREACHABLE(); |
10783 } | 10282 } |
10784 | 10283 |
10785 | 10284 |
10786 void Parser::ReportWarning(TokenPosition token_pos, | 10285 void Parser::ReportWarning(TokenPosition token_pos, |
10787 const char* format, ...) const { | 10286 const char* format, |
| 10287 ...) const { |
10788 va_list args; | 10288 va_list args; |
10789 va_start(args, format); | 10289 va_start(args, format); |
10790 Report::MessageV(Report::kWarning, | 10290 Report::MessageV(Report::kWarning, script_, token_pos, Report::AtLocation, |
10791 script_, token_pos, Report::AtLocation, format, args); | 10291 format, args); |
10792 va_end(args); | 10292 va_end(args); |
10793 } | 10293 } |
10794 | 10294 |
10795 | 10295 |
10796 void Parser::ReportWarning(const char* format, ...) const { | 10296 void Parser::ReportWarning(const char* format, ...) const { |
10797 va_list args; | 10297 va_list args; |
10798 va_start(args, format); | 10298 va_start(args, format); |
10799 Report::MessageV(Report::kWarning, | 10299 Report::MessageV(Report::kWarning, script_, TokenPos(), Report::AtLocation, |
10800 script_, TokenPos(), Report::AtLocation, format, args); | 10300 format, args); |
10801 va_end(args); | 10301 va_end(args); |
10802 } | 10302 } |
10803 | 10303 |
10804 | 10304 |
10805 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { | 10305 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { |
10806 if (CurrentToken() != token_expected) { | 10306 if (CurrentToken() != token_expected) { |
10807 if (msg != NULL) { | 10307 if (msg != NULL) { |
10808 ReportError("%s", msg); | 10308 ReportError("%s", msg); |
10809 } else { | 10309 } else { |
10810 ReportError("'%s' expected", Token::Str(token_expected)); | 10310 ReportError("'%s' expected", Token::Str(token_expected)); |
(...skipping 12 matching lines...) Expand all Loading... |
10823 | 10323 |
10824 void Parser::ExpectSemicolon() { | 10324 void Parser::ExpectSemicolon() { |
10825 if (CurrentToken() != Token::kSEMICOLON) { | 10325 if (CurrentToken() != Token::kSEMICOLON) { |
10826 ReportErrorBefore("semicolon expected"); | 10326 ReportErrorBefore("semicolon expected"); |
10827 } | 10327 } |
10828 ConsumeToken(); | 10328 ConsumeToken(); |
10829 } | 10329 } |
10830 | 10330 |
10831 | 10331 |
10832 void Parser::UnexpectedToken() { | 10332 void Parser::UnexpectedToken() { |
10833 ReportError("unexpected token '%s'", | 10333 ReportError("unexpected token '%s'", CurrentToken() == Token::kIDENT |
10834 CurrentToken() == Token::kIDENT ? | 10334 ? CurrentLiteral()->ToCString() |
10835 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); | 10335 : Token::Str(CurrentToken())); |
10836 } | 10336 } |
10837 | 10337 |
10838 | 10338 |
10839 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { | 10339 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { |
10840 if (CurrentToken() != Token::kIDENT) { | 10340 if (CurrentToken() != Token::kIDENT) { |
10841 ReportError("%s", msg); | 10341 ReportError("%s", msg); |
10842 } | 10342 } |
10843 String* ident = CurrentLiteral(); | 10343 String* ident = CurrentLiteral(); |
10844 if (ident->Equals("dynamic")) { | 10344 if (ident->Equals("dynamic")) { |
10845 ReportError("%s", msg); | 10345 ReportError("%s", msg); |
10846 } | 10346 } |
10847 ConsumeToken(); | 10347 ConsumeToken(); |
10848 return ident; | 10348 return ident; |
10849 } | 10349 } |
10850 | 10350 |
10851 | 10351 |
10852 // Check whether current token is an identifier or a built-in identifier. | 10352 // Check whether current token is an identifier or a built-in identifier. |
10853 String* Parser::ExpectIdentifier(const char* msg) { | 10353 String* Parser::ExpectIdentifier(const char* msg) { |
10854 if (!IsIdentifier()) { | 10354 if (!IsIdentifier()) { |
10855 ReportError("%s", msg); | 10355 ReportError("%s", msg); |
10856 } | 10356 } |
10857 String* ident = CurrentLiteral(); | 10357 String* ident = CurrentLiteral(); |
10858 ConsumeToken(); | 10358 ConsumeToken(); |
10859 return ident; | 10359 return ident; |
10860 } | 10360 } |
10861 | 10361 |
10862 | 10362 |
10863 bool Parser::IsAwaitKeyword() { | 10363 bool Parser::IsAwaitKeyword() { |
10864 return (FLAG_await_is_keyword || await_is_keyword_) && | 10364 return (FLAG_await_is_keyword || await_is_keyword_) && |
10865 IsSymbol(Symbols::Await()); | 10365 IsSymbol(Symbols::Await()); |
10866 } | 10366 } |
10867 | 10367 |
10868 | 10368 |
10869 bool Parser::IsYieldKeyword() { | 10369 bool Parser::IsYieldKeyword() { |
10870 return (FLAG_await_is_keyword || await_is_keyword_) && | 10370 return (FLAG_await_is_keyword || await_is_keyword_) && |
10871 IsSymbol(Symbols::YieldKw()); | 10371 IsSymbol(Symbols::YieldKw()); |
10872 } | 10372 } |
10873 | 10373 |
10874 | 10374 |
10875 static bool IsIncrementOperator(Token::Kind token) { | 10375 static bool IsIncrementOperator(Token::Kind token) { |
10876 return token == Token::kINCR || token == Token::kDECR; | 10376 return token == Token::kINCR || token == Token::kDECR; |
10877 } | 10377 } |
10878 | 10378 |
10879 | 10379 |
10880 static bool IsPrefixOperator(Token::Kind token) { | 10380 static bool IsPrefixOperator(Token::Kind token) { |
10881 return (token == Token::kSUB) || | 10381 return (token == Token::kSUB) || (token == Token::kNOT) || |
10882 (token == Token::kNOT) || | |
10883 (token == Token::kBIT_NOT); | 10382 (token == Token::kBIT_NOT); |
10884 } | 10383 } |
10885 | 10384 |
10886 | 10385 |
10887 SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos, | 10386 SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos, |
10888 AstNode* node, | 10387 AstNode* node, |
10889 LocalScope* scope) { | 10388 LocalScope* scope) { |
10890 if ((node == NULL) || !node->IsSequenceNode()) { | 10389 if ((node == NULL) || !node->IsSequenceNode()) { |
10891 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); | 10390 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); |
10892 if (node != NULL) { | 10391 if (node != NULL) { |
10893 sequence->Add(node); | 10392 sequence->Add(node); |
10894 } | 10393 } |
10895 return sequence; | 10394 return sequence; |
10896 } | 10395 } |
10897 return node->AsSequenceNode(); | 10396 return node->AsSequenceNode(); |
10898 } | 10397 } |
10899 | 10398 |
10900 | 10399 |
10901 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10400 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
10902 AstNode* Parser::ThrowTypeError(TokenPosition type_pos, | 10401 AstNode* Parser::ThrowTypeError(TokenPosition type_pos, |
10903 const AbstractType& type, | 10402 const AbstractType& type, |
10904 LibraryPrefix* prefix) { | 10403 LibraryPrefix* prefix) { |
10905 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); | 10404 ArgumentListNode* arguments = new (Z) ArgumentListNode(type_pos); |
10906 | 10405 |
10907 String& method_name = String::Handle(Z); | 10406 String& method_name = String::Handle(Z); |
10908 if (prefix == NULL) { | 10407 if (prefix == NULL) { |
10909 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | 10408 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); |
10910 } else { | 10409 } else { |
10911 arguments->Add(new(Z) LiteralNode(type_pos, *prefix)); | 10410 arguments->Add(new (Z) LiteralNode(type_pos, *prefix)); |
10912 method_name = Library::PrivateCoreLibName( | 10411 method_name = |
10913 Symbols::ThrowNewIfNotLoaded()).raw(); | 10412 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw(); |
10914 } | 10413 } |
10915 // Location argument. | 10414 // Location argument. |
10916 arguments->Add(new(Z) LiteralNode( | 10415 arguments->Add(new (Z) LiteralNode( |
10917 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos.value(), | 10416 type_pos, |
10918 Heap::kOld)))); | 10417 Integer::ZoneHandle(Z, Integer::New(type_pos.value(), Heap::kOld)))); |
10919 // Src value argument. | 10418 // Src value argument. |
10920 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); | 10419 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); |
10921 // Dst type argument. | 10420 // Dst type argument. |
10922 arguments->Add(new(Z) LiteralNode(type_pos, type)); | 10421 arguments->Add(new (Z) LiteralNode(type_pos, type)); |
10923 // Dst name argument. | 10422 // Dst name argument. |
10924 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); | 10423 arguments->Add(new (Z) LiteralNode(type_pos, Symbols::Empty())); |
10925 // Bound error msg argument. | 10424 // Bound error msg argument. |
10926 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); | 10425 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); |
10927 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); | 10426 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); |
10928 } | 10427 } |
10929 | 10428 |
10930 | 10429 |
10931 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10430 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
10932 AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos, | 10431 AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos, |
10933 const Class& cls, | 10432 const Class& cls, |
10934 const String& function_name, | 10433 const String& function_name, |
10935 ArgumentListNode* function_arguments, | 10434 ArgumentListNode* function_arguments, |
10936 InvocationMirror::Call im_call, | 10435 InvocationMirror::Call im_call, |
10937 InvocationMirror::Type im_type, | 10436 InvocationMirror::Type im_type, |
10938 const Function* func, | 10437 const Function* func, |
10939 const LibraryPrefix* prefix) { | 10438 const LibraryPrefix* prefix) { |
10940 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); | 10439 ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos); |
10941 | 10440 |
10942 String& method_name = String::Handle(Z); | 10441 String& method_name = String::Handle(Z); |
10943 if (prefix == NULL) { | 10442 if (prefix == NULL) { |
10944 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | 10443 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); |
10945 } else { | 10444 } else { |
10946 arguments->Add(new(Z) LiteralNode(call_pos, *prefix)); | 10445 arguments->Add(new (Z) LiteralNode(call_pos, *prefix)); |
10947 method_name = Library::PrivateCoreLibName( | 10446 method_name = |
10948 Symbols::ThrowNewIfNotLoaded()).raw(); | 10447 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw(); |
10949 } | 10448 } |
10950 // Object receiver. | 10449 // Object receiver. |
10951 // If the function is external and dynamic, pass the actual receiver, | 10450 // If the function is external and dynamic, pass the actual receiver, |
10952 // otherwise, pass a class literal of the unresolved method's owner. | 10451 // otherwise, pass a class literal of the unresolved method's owner. |
10953 if ((func != NULL) && !func->IsNull() && | 10452 if ((func != NULL) && !func->IsNull() && func->is_external() && |
10954 func->is_external() && !func->is_static()) { | 10453 !func->is_static()) { |
10955 arguments->Add(LoadReceiver(func->token_pos())); | 10454 arguments->Add(LoadReceiver(func->token_pos())); |
10956 } else { | 10455 } else { |
10957 AbstractType& type = AbstractType::ZoneHandle(Z); | 10456 AbstractType& type = AbstractType::ZoneHandle(Z); |
10958 type ^= Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld); | 10457 type ^= Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld); |
10959 type ^= ClassFinalizer::FinalizeType( | 10458 type ^= ClassFinalizer::FinalizeType(current_class(), type, |
10960 current_class(), type, ClassFinalizer::kCanonicalize); | 10459 ClassFinalizer::kCanonicalize); |
10961 arguments->Add(new(Z) LiteralNode(call_pos, type)); | 10460 arguments->Add(new (Z) LiteralNode(call_pos, type)); |
10962 } | 10461 } |
10963 // String memberName. | 10462 // String memberName. |
10964 arguments->Add(new(Z) LiteralNode( | 10463 arguments->Add(new (Z) LiteralNode( |
10965 call_pos, String::ZoneHandle(Z, Symbols::New(T, function_name)))); | 10464 call_pos, String::ZoneHandle(Z, Symbols::New(T, function_name)))); |
10966 // Smi invocation_type. | 10465 // Smi invocation_type. |
10967 if (cls.IsTopLevel()) { | 10466 if (cls.IsTopLevel()) { |
10968 ASSERT(im_call == InvocationMirror::kStatic || | 10467 ASSERT(im_call == InvocationMirror::kStatic || |
10969 im_call == InvocationMirror::kTopLevel); | 10468 im_call == InvocationMirror::kTopLevel); |
10970 im_call = InvocationMirror::kTopLevel; | 10469 im_call = InvocationMirror::kTopLevel; |
10971 } | 10470 } |
10972 arguments->Add(new(Z) LiteralNode(call_pos, Smi::ZoneHandle(Z, | 10471 arguments->Add(new (Z) LiteralNode( |
10973 Smi::New(InvocationMirror::EncodeType(im_call, im_type))))); | 10472 call_pos, Smi::ZoneHandle(Z, Smi::New(InvocationMirror::EncodeType( |
| 10473 im_call, im_type))))); |
10974 // List arguments. | 10474 // List arguments. |
10975 if (function_arguments == NULL) { | 10475 if (function_arguments == NULL) { |
10976 arguments->Add(new(Z) LiteralNode(call_pos, Object::null_array())); | 10476 arguments->Add(new (Z) LiteralNode(call_pos, Object::null_array())); |
10977 } else { | 10477 } else { |
10978 ArrayNode* array = new(Z) ArrayNode( | 10478 ArrayNode* array = |
10979 call_pos, | 10479 new (Z) ArrayNode(call_pos, Type::ZoneHandle(Z, Type::ArrayType()), |
10980 Type::ZoneHandle(Z, Type::ArrayType()), | 10480 function_arguments->nodes()); |
10981 function_arguments->nodes()); | |
10982 arguments->Add(array); | 10481 arguments->Add(array); |
10983 } | 10482 } |
10984 // List argumentNames. | 10483 // List argumentNames. |
10985 if (function_arguments == NULL) { | 10484 if (function_arguments == NULL) { |
10986 arguments->Add(new(Z) LiteralNode(call_pos, Object::null_array())); | 10485 arguments->Add(new (Z) LiteralNode(call_pos, Object::null_array())); |
10987 } else { | 10486 } else { |
10988 arguments->Add(new(Z) LiteralNode(call_pos, function_arguments->names())); | 10487 arguments->Add(new (Z) LiteralNode(call_pos, function_arguments->names())); |
10989 } | 10488 } |
10990 | 10489 |
10991 // List existingArgumentNames. | 10490 // List existingArgumentNames. |
10992 // Check if there exists a function with the same name unless caller | 10491 // Check if there exists a function with the same name unless caller |
10993 // has done the lookup already. If there is a function with the same | 10492 // has done the lookup already. If there is a function with the same |
10994 // name but incompatible parameters, inform the NoSuchMethodError what the | 10493 // name but incompatible parameters, inform the NoSuchMethodError what the |
10995 // expected parameters are. | 10494 // expected parameters are. |
10996 Function& function = Function::Handle(Z); | 10495 Function& function = Function::Handle(Z); |
10997 if (func != NULL) { | 10496 if (func != NULL) { |
10998 function = func->raw(); | 10497 function = func->raw(); |
(...skipping 11 matching lines...) Expand all Loading... |
11010 // Since the NoSuchMethodError class only uses the list to produce | 10509 // Since the NoSuchMethodError class only uses the list to produce |
11011 // a string describing the expected parameters, we construct a more | 10510 // a string describing the expected parameters, we construct a more |
11012 // descriptive string here and pass it as the only element of the | 10511 // descriptive string here and pass it as the only element of the |
11013 // "existingArgumentNames" array of the NoSuchMethodError constructor. | 10512 // "existingArgumentNames" array of the NoSuchMethodError constructor. |
11014 // TODO(13471): Separate the implementations of NoSuchMethodError | 10513 // TODO(13471): Separate the implementations of NoSuchMethodError |
11015 // between dart2js and VM. Update the constructor to accept a string | 10514 // between dart2js and VM. Update the constructor to accept a string |
11016 // describing the formal parameters of an incompatible call target. | 10515 // describing the formal parameters of an incompatible call target. |
11017 array = Array::New(1, Heap::kOld); | 10516 array = Array::New(1, Heap::kOld); |
11018 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); | 10517 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); |
11019 } | 10518 } |
11020 arguments->Add(new(Z) LiteralNode(call_pos, array)); | 10519 arguments->Add(new (Z) LiteralNode(call_pos, array)); |
11021 | 10520 |
11022 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); | 10521 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); |
11023 } | 10522 } |
11024 | 10523 |
11025 | 10524 |
11026 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 10525 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
11027 TRACE_PARSER("ParseBinaryExpr"); | 10526 TRACE_PARSER("ParseBinaryExpr"); |
11028 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10527 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
11029 AstNode* left_operand = ParseUnaryExpr(); | 10528 AstNode* left_operand = ParseUnaryExpr(); |
11030 if (left_operand->IsPrimaryNode() && | 10529 if (left_operand->IsPrimaryNode() && |
11031 (left_operand->AsPrimaryNode()->IsSuper())) { | 10530 (left_operand->AsPrimaryNode()->IsSuper())) { |
11032 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10531 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
11033 } | 10532 } |
11034 int current_preced = Token::Precedence(CurrentToken()); | 10533 int current_preced = Token::Precedence(CurrentToken()); |
11035 while (current_preced >= min_preced) { | 10534 while (current_preced >= min_preced) { |
11036 while (Token::Precedence(CurrentToken()) == current_preced) { | 10535 while (Token::Precedence(CurrentToken()) == current_preced) { |
11037 Token::Kind op_kind = CurrentToken(); | 10536 Token::Kind op_kind = CurrentToken(); |
11038 const TokenPosition op_pos = TokenPos(); | 10537 const TokenPosition op_pos = TokenPos(); |
11039 ConsumeToken(); | 10538 ConsumeToken(); |
11040 AstNode* right_operand = NULL; | 10539 AstNode* right_operand = NULL; |
11041 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 10540 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
11042 right_operand = ParseBinaryExpr(current_preced + 1); | 10541 right_operand = ParseBinaryExpr(current_preced + 1); |
11043 } else { | 10542 } else { |
11044 // For 'is' and 'as' we expect the right operand to be a type. | 10543 // For 'is' and 'as' we expect the right operand to be a type. |
11045 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { | 10544 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { |
11046 ConsumeToken(); | 10545 ConsumeToken(); |
11047 op_kind = Token::kISNOT; | 10546 op_kind = Token::kISNOT; |
11048 } | 10547 } |
11049 const TokenPosition type_pos = TokenPos(); | 10548 const TokenPosition type_pos = TokenPos(); |
11050 const AbstractType& type = AbstractType::ZoneHandle(Z, | 10549 const AbstractType& type = AbstractType::ZoneHandle( |
11051 ParseType(ClassFinalizer::kCanonicalize)); | 10550 Z, ParseType(ClassFinalizer::kCanonicalize)); |
11052 if (!type.IsInstantiated() && (FunctionLevel() > 0)) { | 10551 if (!type.IsInstantiated() && (FunctionLevel() > 0)) { |
11053 // Make sure that the instantiator is captured. | 10552 // Make sure that the instantiator is captured. |
11054 CaptureInstantiator(); | 10553 CaptureInstantiator(); |
11055 } | 10554 } |
11056 right_operand = new(Z) TypeNode(type_pos, type); | 10555 right_operand = new (Z) TypeNode(type_pos, type); |
11057 // In production mode, the type may be malformed. | 10556 // In production mode, the type may be malformed. |
11058 // In checked mode, the type may be malformed or malbounded. | 10557 // In checked mode, the type may be malformed or malbounded. |
11059 if (type.IsMalformedOrMalbounded()) { | 10558 if (type.IsMalformedOrMalbounded()) { |
11060 // Note that a type error is thrown in a type test or in | 10559 // Note that a type error is thrown in a type test or in |
11061 // a type cast even if the tested value is null. | 10560 // a type cast even if the tested value is null. |
11062 // We need to evaluate the left operand for potential | 10561 // We need to evaluate the left operand for potential |
11063 // side effects. | 10562 // side effects. |
11064 LetNode* let = new(Z) LetNode(left_operand->token_pos()); | 10563 LetNode* let = new (Z) LetNode(left_operand->token_pos()); |
11065 let->AddNode(left_operand); | 10564 let->AddNode(left_operand); |
11066 let->AddNode(ThrowTypeError(type_pos, type)); | 10565 let->AddNode(ThrowTypeError(type_pos, type)); |
11067 left_operand = let; | 10566 left_operand = let; |
11068 break; // Type checks and casts can't be chained. | 10567 break; // Type checks and casts can't be chained. |
11069 } | 10568 } |
11070 } | 10569 } |
11071 if (Token::IsRelationalOperator(op_kind) | 10570 if (Token::IsRelationalOperator(op_kind) || |
11072 || Token::IsTypeTestOperator(op_kind) | 10571 Token::IsTypeTestOperator(op_kind) || |
11073 || Token::IsTypeCastOperator(op_kind) | 10572 Token::IsTypeCastOperator(op_kind) || |
11074 || Token::IsEqualityOperator(op_kind)) { | 10573 Token::IsEqualityOperator(op_kind)) { |
11075 left_operand = new(Z) ComparisonNode( | 10574 left_operand = new (Z) |
11076 op_pos, op_kind, left_operand, right_operand); | 10575 ComparisonNode(op_pos, op_kind, left_operand, right_operand); |
11077 break; // Equality and relational operators cannot be chained. | 10576 break; // Equality and relational operators cannot be chained. |
11078 } else { | 10577 } else { |
11079 left_operand = OptimizeBinaryOpNode( | 10578 left_operand = |
11080 op_pos, op_kind, left_operand, right_operand); | 10579 OptimizeBinaryOpNode(op_pos, op_kind, left_operand, right_operand); |
11081 } | 10580 } |
11082 } | 10581 } |
11083 current_preced--; | 10582 current_preced--; |
11084 } | 10583 } |
11085 return left_operand; | 10584 return left_operand; |
11086 } | 10585 } |
11087 | 10586 |
11088 | 10587 |
11089 AstNode* Parser::ParseAwaitableExprList() { | 10588 AstNode* Parser::ParseAwaitableExprList() { |
11090 TRACE_PARSER("ParseAwaitableExprList"); | 10589 TRACE_PARSER("ParseAwaitableExprList"); |
11091 SequenceNode* preamble = NULL; | 10590 SequenceNode* preamble = NULL; |
11092 AstNode* expressions = ParseAwaitableExpr( | 10591 AstNode* expressions = |
11093 kAllowConst, kConsumeCascades, &preamble); | 10592 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); |
11094 if (preamble != NULL) { | 10593 if (preamble != NULL) { |
11095 preamble->Add(expressions); | 10594 preamble->Add(expressions); |
11096 expressions = preamble; | 10595 expressions = preamble; |
11097 } | 10596 } |
11098 if (CurrentToken() == Token::kCOMMA) { | 10597 if (CurrentToken() == Token::kCOMMA) { |
11099 // Collect comma-separated expressions in a non scope owning sequence node. | 10598 // Collect comma-separated expressions in a non scope owning sequence node. |
11100 SequenceNode* list = new(Z) SequenceNode(TokenPos(), NULL); | 10599 SequenceNode* list = new (Z) SequenceNode(TokenPos(), NULL); |
11101 list->Add(expressions); | 10600 list->Add(expressions); |
11102 while (CurrentToken() == Token::kCOMMA) { | 10601 while (CurrentToken() == Token::kCOMMA) { |
11103 ConsumeToken(); | 10602 ConsumeToken(); |
11104 preamble = NULL; | 10603 preamble = NULL; |
11105 AstNode* expr = ParseAwaitableExpr( | 10604 AstNode* expr = |
11106 kAllowConst, kConsumeCascades, &preamble); | 10605 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); |
11107 if (preamble != NULL) { | 10606 if (preamble != NULL) { |
11108 list->Add(preamble); | 10607 list->Add(preamble); |
11109 } | 10608 } |
11110 list->Add(expr); | 10609 list->Add(expr); |
11111 } | 10610 } |
11112 expressions = list; | 10611 expressions = list; |
11113 } | 10612 } |
11114 return expressions; | 10613 return expressions; |
11115 } | 10614 } |
11116 | 10615 |
11117 | 10616 |
11118 void Parser::EnsureExpressionTemp() { | 10617 void Parser::EnsureExpressionTemp() { |
11119 // Temporary used later by the flow_graph_builder. | 10618 // Temporary used later by the flow_graph_builder. |
11120 parsed_function()->EnsureExpressionTemp(); | 10619 parsed_function()->EnsureExpressionTemp(); |
11121 } | 10620 } |
11122 | 10621 |
11123 | 10622 |
11124 LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos, | 10623 LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos, |
11125 const char* s) { | 10624 const char* s) { |
11126 char name[64]; | 10625 char name[64]; |
11127 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); | 10626 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); |
11128 LocalVariable* temp = new(Z) LocalVariable( | 10627 LocalVariable* temp = new (Z) LocalVariable( |
11129 token_pos, | 10628 token_pos, token_pos, String::ZoneHandle(Z, Symbols::New(T, name)), |
11130 token_pos, | |
11131 String::ZoneHandle(Z, Symbols::New(T, name)), | |
11132 Object::dynamic_type()); | 10629 Object::dynamic_type()); |
11133 temp->set_is_final(); | 10630 temp->set_is_final(); |
11134 current_block_->scope->AddVariable(temp); | 10631 current_block_->scope->AddVariable(temp); |
11135 return temp; | 10632 return temp; |
11136 } | 10633 } |
11137 | 10634 |
11138 | 10635 |
11139 AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos, | 10636 AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos, |
11140 Token::Kind binary_op, | 10637 Token::Kind binary_op, |
11141 AstNode* lhs, | 10638 AstNode* lhs, |
11142 AstNode* rhs) { | 10639 AstNode* rhs) { |
11143 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 10640 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
11144 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 10641 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
11145 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 10642 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
11146 if (lhs_literal->literal().IsDouble() && | 10643 if (lhs_literal->literal().IsDouble() && |
11147 rhs_literal->literal().IsDouble()) { | 10644 rhs_literal->literal().IsDouble()) { |
11148 double left_double = Double::Cast(lhs_literal->literal()).value(); | 10645 double left_double = Double::Cast(lhs_literal->literal()).value(); |
11149 double right_double = Double::Cast(rhs_literal->literal()).value(); | 10646 double right_double = Double::Cast(rhs_literal->literal()).value(); |
11150 if (binary_op == Token::kDIV) { | 10647 if (binary_op == Token::kDIV) { |
11151 const Double& dbl_obj = Double::ZoneHandle(Z, | 10648 const Double& dbl_obj = Double::ZoneHandle( |
11152 Double::NewCanonical((left_double / right_double))); | 10649 Z, Double::NewCanonical((left_double / right_double))); |
11153 return new(Z) LiteralNode(op_pos, dbl_obj); | 10650 return new (Z) LiteralNode(op_pos, dbl_obj); |
11154 } | 10651 } |
11155 } | 10652 } |
11156 } | 10653 } |
11157 if (binary_op == Token::kBIT_AND) { | 10654 if (binary_op == Token::kBIT_AND) { |
11158 // Normalize so that rhs is a literal if any is. | 10655 // Normalize so that rhs is a literal if any is. |
11159 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { | 10656 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { |
11160 // Swap. | 10657 // Swap. |
11161 LiteralNode* temp = rhs_literal; | 10658 LiteralNode* temp = rhs_literal; |
11162 rhs_literal = lhs_literal; | 10659 rhs_literal = lhs_literal; |
11163 lhs_literal = temp; | 10660 lhs_literal = temp; |
11164 } | 10661 } |
11165 } | 10662 } |
11166 if (binary_op == Token::kIFNULL) { | 10663 if (binary_op == Token::kIFNULL) { |
11167 // Handle a ?? b. | 10664 // Handle a ?? b. |
11168 if ((lhs->EvalConstExpr() != NULL) && (rhs->EvalConstExpr() != NULL)) { | 10665 if ((lhs->EvalConstExpr() != NULL) && (rhs->EvalConstExpr() != NULL)) { |
11169 Instance& expr_value = Instance::ZoneHandle(Z, | 10666 Instance& expr_value = Instance::ZoneHandle( |
11170 EvaluateConstExpr(lhs->token_pos(), lhs).raw()); | 10667 Z, EvaluateConstExpr(lhs->token_pos(), lhs).raw()); |
11171 if (expr_value.IsNull()) { | 10668 if (expr_value.IsNull()) { |
11172 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); | 10669 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); |
11173 } | 10670 } |
11174 return new(Z) LiteralNode(op_pos, expr_value); | 10671 return new (Z) LiteralNode(op_pos, expr_value); |
11175 } | 10672 } |
11176 | 10673 |
11177 LetNode* result = new(Z) LetNode(op_pos); | 10674 LetNode* result = new (Z) LetNode(op_pos); |
11178 LocalVariable* left_temp = result->AddInitializer(lhs); | 10675 LocalVariable* left_temp = result->AddInitializer(lhs); |
11179 left_temp->set_is_final(); | 10676 left_temp->set_is_final(); |
11180 const TokenPosition no_pos = TokenPosition::kNoSource; | 10677 const TokenPosition no_pos = TokenPosition::kNoSource; |
11181 LiteralNode* null_operand = | 10678 LiteralNode* null_operand = |
11182 new(Z) LiteralNode(no_pos, Object::null_instance()); | 10679 new (Z) LiteralNode(no_pos, Object::null_instance()); |
11183 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); | 10680 LoadLocalNode* load_left_temp = new (Z) LoadLocalNode(no_pos, left_temp); |
11184 ComparisonNode* null_compare = | 10681 ComparisonNode* null_compare = new (Z) |
11185 new(Z) ComparisonNode(no_pos, | 10682 ComparisonNode(no_pos, Token::kNE_STRICT, load_left_temp, null_operand); |
11186 Token::kNE_STRICT, | 10683 result->AddNode( |
11187 load_left_temp, | 10684 new (Z) ConditionalExprNode(op_pos, null_compare, load_left_temp, rhs)); |
11188 null_operand); | |
11189 result->AddNode(new(Z) ConditionalExprNode(op_pos, | |
11190 null_compare, | |
11191 load_left_temp, | |
11192 rhs)); | |
11193 return result; | 10685 return result; |
11194 } | 10686 } |
11195 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 10687 return new (Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
11196 } | 10688 } |
11197 | 10689 |
11198 | 10690 |
11199 AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos, | 10691 AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos, |
11200 Token::Kind assignment_op, | 10692 Token::Kind assignment_op, |
11201 AstNode* lhs, | 10693 AstNode* lhs, |
11202 AstNode* rhs) { | 10694 AstNode* rhs) { |
11203 TRACE_PARSER("ExpandAssignableOp"); | 10695 TRACE_PARSER("ExpandAssignableOp"); |
11204 switch (assignment_op) { | 10696 switch (assignment_op) { |
11205 case Token::kASSIGN: | 10697 case Token::kASSIGN: |
11206 return rhs; | 10698 return rhs; |
11207 case Token::kASSIGN_ADD: | 10699 case Token::kASSIGN_ADD: |
11208 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 10700 return new (Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
11209 case Token::kASSIGN_SUB: | 10701 case Token::kASSIGN_SUB: |
11210 return new(Z) BinaryOpNode(op_pos, Token::kSUB, lhs, rhs); | 10702 return new (Z) BinaryOpNode(op_pos, Token::kSUB, lhs, rhs); |
11211 case Token::kASSIGN_MUL: | 10703 case Token::kASSIGN_MUL: |
11212 return new(Z) BinaryOpNode(op_pos, Token::kMUL, lhs, rhs); | 10704 return new (Z) BinaryOpNode(op_pos, Token::kMUL, lhs, rhs); |
11213 case Token::kASSIGN_TRUNCDIV: | 10705 case Token::kASSIGN_TRUNCDIV: |
11214 return new(Z) BinaryOpNode(op_pos, Token::kTRUNCDIV, lhs, rhs); | 10706 return new (Z) BinaryOpNode(op_pos, Token::kTRUNCDIV, lhs, rhs); |
11215 case Token::kASSIGN_DIV: | 10707 case Token::kASSIGN_DIV: |
11216 return new(Z) BinaryOpNode(op_pos, Token::kDIV, lhs, rhs); | 10708 return new (Z) BinaryOpNode(op_pos, Token::kDIV, lhs, rhs); |
11217 case Token::kASSIGN_MOD: | 10709 case Token::kASSIGN_MOD: |
11218 return new(Z) BinaryOpNode(op_pos, Token::kMOD, lhs, rhs); | 10710 return new (Z) BinaryOpNode(op_pos, Token::kMOD, lhs, rhs); |
11219 case Token::kASSIGN_SHR: | 10711 case Token::kASSIGN_SHR: |
11220 return new(Z) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); | 10712 return new (Z) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); |
11221 case Token::kASSIGN_SHL: | 10713 case Token::kASSIGN_SHL: |
11222 return new(Z) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); | 10714 return new (Z) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); |
11223 case Token::kASSIGN_OR: | 10715 case Token::kASSIGN_OR: |
11224 return new(Z) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); | 10716 return new (Z) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); |
11225 case Token::kASSIGN_AND: | 10717 case Token::kASSIGN_AND: |
11226 return new(Z) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); | 10718 return new (Z) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); |
11227 case Token::kASSIGN_XOR: | 10719 case Token::kASSIGN_XOR: |
11228 return new(Z) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); | 10720 return new (Z) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); |
11229 case Token::kASSIGN_COND: | 10721 case Token::kASSIGN_COND: |
11230 return new(Z) BinaryOpNode(op_pos, Token::kIFNULL, lhs, rhs); | 10722 return new (Z) BinaryOpNode(op_pos, Token::kIFNULL, lhs, rhs); |
11231 default: | 10723 default: |
11232 ReportError(op_pos, | 10724 ReportError(op_pos, |
11233 "internal error: ExpandAssignableOp '%s' unimplemented", | 10725 "internal error: ExpandAssignableOp '%s' unimplemented", |
11234 Token::Name(assignment_op)); | 10726 Token::Name(assignment_op)); |
11235 UNIMPLEMENTED(); | 10727 UNIMPLEMENTED(); |
11236 return NULL; | 10728 return NULL; |
11237 } | 10729 } |
11238 } | 10730 } |
11239 | 10731 |
11240 | 10732 |
11241 // Evaluates the value of the compile time constant expression | 10733 // Evaluates the value of the compile time constant expression |
11242 // and returns a literal node for the value. | 10734 // and returns a literal node for the value. |
11243 LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) { | 10735 LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) { |
11244 if (expr->IsLiteralNode()) { | 10736 if (expr->IsLiteralNode()) { |
11245 return expr->AsLiteralNode(); | 10737 return expr->AsLiteralNode(); |
11246 } | 10738 } |
11247 if (expr->EvalConstExpr() == NULL) { | 10739 if (expr->EvalConstExpr() == NULL) { |
11248 ReportError(expr_pos, "expression is not a valid compile-time constant"); | 10740 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
11249 } | 10741 } |
11250 return new(Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr)); | 10742 return new (Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr)); |
11251 } | 10743 } |
11252 | 10744 |
11253 | 10745 |
11254 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 10746 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
11255 AstNode* node = *expr; | 10747 AstNode* node = *expr; |
11256 TokenPosition token_pos = node->token_pos(); | 10748 TokenPosition token_pos = node->token_pos(); |
11257 LetNode* result = new(Z) LetNode(token_pos); | 10749 LetNode* result = new (Z) LetNode(token_pos); |
11258 if (node->IsLoadIndexedNode()) { | 10750 if (node->IsLoadIndexedNode()) { |
11259 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 10751 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
11260 AstNode* array = load_indexed->array(); | 10752 AstNode* array = load_indexed->array(); |
11261 AstNode* index = load_indexed->index_expr(); | 10753 AstNode* index = load_indexed->index_expr(); |
11262 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 10754 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
11263 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 10755 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
11264 array = new(Z) LoadLocalNode(token_pos, t0); | 10756 array = new (Z) LoadLocalNode(token_pos, t0); |
11265 } | 10757 } |
11266 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { | 10758 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { |
11267 LocalVariable* t1 = result->AddInitializer( | 10759 LocalVariable* t1 = result->AddInitializer(load_indexed->index_expr()); |
11268 load_indexed->index_expr()); | 10760 index = new (Z) LoadLocalNode(token_pos, t1); |
11269 index = new(Z) LoadLocalNode(token_pos, t1); | |
11270 } | 10761 } |
11271 *expr = new(Z) LoadIndexedNode(token_pos, | 10762 *expr = new (Z) |
11272 array, | 10763 LoadIndexedNode(token_pos, array, index, load_indexed->super_class()); |
11273 index, | |
11274 load_indexed->super_class()); | |
11275 return result; | 10764 return result; |
11276 } | 10765 } |
11277 if (node->IsInstanceGetterNode()) { | 10766 if (node->IsInstanceGetterNode()) { |
11278 InstanceGetterNode* getter = node->AsInstanceGetterNode(); | 10767 InstanceGetterNode* getter = node->AsInstanceGetterNode(); |
11279 AstNode* receiver = getter->receiver(); | 10768 AstNode* receiver = getter->receiver(); |
11280 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { | 10769 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { |
11281 LocalVariable* t0 = result->AddInitializer(getter->receiver()); | 10770 LocalVariable* t0 = result->AddInitializer(getter->receiver()); |
11282 receiver = new(Z) LoadLocalNode(token_pos, t0); | 10771 receiver = new (Z) LoadLocalNode(token_pos, t0); |
11283 } | 10772 } |
11284 *expr = new(Z) InstanceGetterNode( | 10773 *expr = new (Z) InstanceGetterNode( |
11285 token_pos, receiver, getter->field_name(), getter->is_conditional()); | 10774 token_pos, receiver, getter->field_name(), getter->is_conditional()); |
11286 return result; | 10775 return result; |
11287 } | 10776 } |
11288 return result; | 10777 return result; |
11289 } | 10778 } |
11290 | 10779 |
11291 | 10780 |
11292 // Check whether the syntax of expression expr is a grammatically legal | 10781 // Check whether the syntax of expression expr is a grammatically legal |
11293 // assignable expression. This check is used to detect situations where | 10782 // assignable expression. This check is used to detect situations where |
11294 // the expression itself is assignable, but the source is grammatically | 10783 // the expression itself is assignable, but the source is grammatically |
(...skipping 22 matching lines...) Expand all Loading... |
11317 TokenPosition left_pos, | 10806 TokenPosition left_pos, |
11318 bool is_compound /* = false */) { | 10807 bool is_compound /* = false */) { |
11319 AstNode* result = original->MakeAssignmentNode(rhs); | 10808 AstNode* result = original->MakeAssignmentNode(rhs); |
11320 if (result == NULL) { | 10809 if (result == NULL) { |
11321 String& name = String::ZoneHandle(Z); | 10810 String& name = String::ZoneHandle(Z); |
11322 const Class* target_cls = ¤t_class(); | 10811 const Class* target_cls = ¤t_class(); |
11323 if (original->IsTypeNode()) { | 10812 if (original->IsTypeNode()) { |
11324 name = Symbols::New(T, original->AsTypeNode()->TypeName()); | 10813 name = Symbols::New(T, original->AsTypeNode()->TypeName()); |
11325 } else if (original->IsLoadStaticFieldNode()) { | 10814 } else if (original->IsLoadStaticFieldNode()) { |
11326 name = original->AsLoadStaticFieldNode()->field().name(); | 10815 name = original->AsLoadStaticFieldNode()->field().name(); |
11327 target_cls = &Class::Handle(Z, | 10816 target_cls = |
11328 original->AsLoadStaticFieldNode()->field().Owner()); | 10817 &Class::Handle(Z, original->AsLoadStaticFieldNode()->field().Owner()); |
11329 } else if ((left_ident != NULL) && | 10818 } else if ((left_ident != NULL) && |
11330 (original->IsLiteralNode() || | 10819 (original->IsLiteralNode() || original->IsLoadLocalNode())) { |
11331 original->IsLoadLocalNode())) { | |
11332 name = left_ident->raw(); | 10820 name = left_ident->raw(); |
11333 } | 10821 } |
11334 if (name.IsNull()) { | 10822 if (name.IsNull()) { |
11335 ReportError(left_pos, "expression is not assignable"); | 10823 ReportError(left_pos, "expression is not assignable"); |
11336 } | 10824 } |
11337 ArgumentListNode* error_arguments = | 10825 ArgumentListNode* error_arguments = |
11338 new(Z) ArgumentListNode(rhs->token_pos()); | 10826 new (Z) ArgumentListNode(rhs->token_pos()); |
11339 error_arguments->Add(rhs); | 10827 error_arguments->Add(rhs); |
11340 result = ThrowNoSuchMethodError( | 10828 result = ThrowNoSuchMethodError(original->token_pos(), *target_cls, |
11341 original->token_pos(), | 10829 String::Handle(Z, Field::SetterName(name)), |
11342 *target_cls, | 10830 error_arguments, InvocationMirror::kStatic, |
11343 String::Handle(Z, Field::SetterName(name)), | 10831 original->IsLoadLocalNode() |
11344 error_arguments, | 10832 ? InvocationMirror::kLocalVar |
11345 InvocationMirror::kStatic, | 10833 : InvocationMirror::kSetter, |
11346 original->IsLoadLocalNode() ? | 10834 NULL); // No existing function. |
11347 InvocationMirror::kLocalVar : InvocationMirror::kSetter, | |
11348 NULL); // No existing function. | |
11349 } | 10835 } |
11350 // The compound assignment operator a ??= b is different from other | 10836 // The compound assignment operator a ??= b is different from other |
11351 // a op= b assignments. If a is non-null, the assignment to a must be | 10837 // a op= b assignments. If a is non-null, the assignment to a must be |
11352 // dropped: | 10838 // dropped: |
11353 // normally: a op= b ==> a = a op b | 10839 // normally: a op= b ==> a = a op b |
11354 // however: a ??= b ==> a ?? (a = b) | 10840 // however: a ??= b ==> a ?? (a = b) |
11355 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) | 10841 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) |
11356 if (is_compound && | 10842 if (is_compound && rhs->IsBinaryOpNode() && |
11357 rhs->IsBinaryOpNode() && | |
11358 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { | 10843 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { |
11359 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); | 10844 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); |
11360 AstNode* modified_assign = | 10845 AstNode* modified_assign = |
11361 CreateAssignmentNode(original, | 10846 CreateAssignmentNode(original, ifnull->right(), left_ident, left_pos); |
11362 ifnull->right(), | 10847 result = OptimizeBinaryOpNode(ifnull->token_pos(), ifnull->kind(), |
11363 left_ident, | 10848 ifnull->left(), modified_assign); |
11364 left_pos); | |
11365 result = OptimizeBinaryOpNode(ifnull->token_pos(), | |
11366 ifnull->kind(), | |
11367 ifnull->left(), | |
11368 modified_assign); | |
11369 } | 10849 } |
11370 return result; | 10850 return result; |
11371 } | 10851 } |
11372 | 10852 |
11373 | 10853 |
11374 AstNode* Parser::ParseCascades(AstNode* expr) { | 10854 AstNode* Parser::ParseCascades(AstNode* expr) { |
11375 TokenPosition cascade_pos = TokenPos(); | 10855 TokenPosition cascade_pos = TokenPos(); |
11376 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10856 LetNode* cascade = new (Z) LetNode(cascade_pos); |
11377 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10857 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
11378 while (CurrentToken() == Token::kCASCADE) { | 10858 while (CurrentToken() == Token::kCASCADE) { |
11379 cascade_pos = TokenPos(); | 10859 cascade_pos = TokenPos(); |
11380 LoadLocalNode* load_cascade_receiver = | 10860 LoadLocalNode* load_cascade_receiver = |
11381 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); | 10861 new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var); |
11382 if (Token::IsIdentifier(LookaheadToken(1))) { | 10862 if (Token::IsIdentifier(LookaheadToken(1))) { |
11383 // Replace .. with . for ParseSelectors(). | 10863 // Replace .. with . for ParseSelectors(). |
11384 token_kind_ = Token::kPERIOD; | 10864 token_kind_ = Token::kPERIOD; |
11385 } else if (LookaheadToken(1) == Token::kLBRACK) { | 10865 } else if (LookaheadToken(1) == Token::kLBRACK) { |
11386 ConsumeToken(); | 10866 ConsumeToken(); |
11387 } else { | 10867 } else { |
11388 ReportError("identifier or [ expected after .."); | 10868 ReportError("identifier or [ expected after .."); |
11389 } | 10869 } |
11390 String* expr_ident = | 10870 String* expr_ident = |
11391 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10871 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
(...skipping 24 matching lines...) Expand all Loading... |
11416 AstNode* assign_expr = | 10896 AstNode* assign_expr = |
11417 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); | 10897 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); |
11418 ASSERT(assign_expr != NULL); | 10898 ASSERT(assign_expr != NULL); |
11419 expr = assign_expr; | 10899 expr = assign_expr; |
11420 } | 10900 } |
11421 } | 10901 } |
11422 cascade->AddNode(expr); | 10902 cascade->AddNode(expr); |
11423 } | 10903 } |
11424 // The result is an expression with the (side effects of the) cascade | 10904 // The result is an expression with the (side effects of the) cascade |
11425 // sequence followed by the (value of the) receiver temp variable load. | 10905 // sequence followed by the (value of the) receiver temp variable load. |
11426 cascade->AddNode(new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); | 10906 cascade->AddNode(new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); |
11427 return cascade; | 10907 return cascade; |
11428 } | 10908 } |
11429 | 10909 |
11430 | 10910 |
11431 // Convert loading of a static const field into a literal node. | 10911 // Convert loading of a static const field into a literal node. |
11432 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { | 10912 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { |
11433 if (expr->IsLoadStaticFieldNode()) { | 10913 if (expr->IsLoadStaticFieldNode()) { |
11434 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 10914 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
11435 if (field.is_const() && | 10915 if (field.is_const() && |
11436 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { | 10916 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { |
11437 ASSERT(field.StaticValue() != Object::sentinel().raw()); | 10917 ASSERT(field.StaticValue() != Object::sentinel().raw()); |
11438 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); | 10918 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); |
11439 return new(zone) LiteralNode( | 10919 return new (zone) LiteralNode( |
11440 expr->token_pos(), | 10920 expr->token_pos(), Instance::ZoneHandle(zone, field.StaticValue())); |
11441 Instance::ZoneHandle(zone, field.StaticValue())); | |
11442 } | 10921 } |
11443 } | 10922 } |
11444 return expr; | 10923 return expr; |
11445 } | 10924 } |
11446 | 10925 |
11447 | 10926 |
11448 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, | 10927 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, |
11449 bool consume_cascades, | 10928 bool consume_cascades, |
11450 SequenceNode** await_preamble) { | 10929 SequenceNode** await_preamble) { |
11451 TRACE_PARSER("ParseAwaitableExpr"); | 10930 TRACE_PARSER("ParseAwaitableExpr"); |
(...skipping 30 matching lines...) Expand all Loading... |
11482 | 10961 |
11483 if (CurrentToken() == Token::kTHROW) { | 10962 if (CurrentToken() == Token::kTHROW) { |
11484 if (require_compiletime_const) { | 10963 if (require_compiletime_const) { |
11485 ReportError("'throw expr' is not a valid compile-time constant"); | 10964 ReportError("'throw expr' is not a valid compile-time constant"); |
11486 } | 10965 } |
11487 ConsumeToken(); | 10966 ConsumeToken(); |
11488 if (CurrentToken() == Token::kSEMICOLON) { | 10967 if (CurrentToken() == Token::kSEMICOLON) { |
11489 ReportError("expression expected after throw"); | 10968 ReportError("expression expected after throw"); |
11490 } | 10969 } |
11491 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 10970 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
11492 return new(Z) ThrowNode(expr_pos, expr, NULL); | 10971 return new (Z) ThrowNode(expr_pos, expr, NULL); |
11493 } | 10972 } |
11494 | 10973 |
11495 if (require_compiletime_const) { | 10974 if (require_compiletime_const) { |
11496 // Check whether we already have evaluated a compile-time constant | 10975 // Check whether we already have evaluated a compile-time constant |
11497 // at this source location. | 10976 // at this source location. |
11498 Instance& existing_const = Instance::ZoneHandle(Z); | 10977 Instance& existing_const = Instance::ZoneHandle(Z); |
11499 if (GetCachedConstant(expr_pos, &existing_const)) { | 10978 if (GetCachedConstant(expr_pos, &existing_const)) { |
11500 SkipConditionalExpr(); | 10979 SkipConditionalExpr(); |
11501 return new(Z) LiteralNode(expr_pos, existing_const); | 10980 return new (Z) LiteralNode(expr_pos, existing_const); |
11502 } | 10981 } |
11503 } | 10982 } |
11504 | 10983 |
11505 AstNode* expr = ParseConditionalExpr(); | 10984 AstNode* expr = ParseConditionalExpr(); |
11506 if (!Token::IsAssignmentOperator(CurrentToken())) { | 10985 if (!Token::IsAssignmentOperator(CurrentToken())) { |
11507 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 10986 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
11508 return ParseCascades(expr); | 10987 return ParseCascades(expr); |
11509 } | 10988 } |
11510 if (require_compiletime_const) { | 10989 if (require_compiletime_const) { |
11511 expr = FoldConstExpr(expr_pos, expr); | 10990 expr = FoldConstExpr(expr_pos, expr); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11561 AstNode* Parser::ParseConditionalExpr() { | 11040 AstNode* Parser::ParseConditionalExpr() { |
11562 TRACE_PARSER("ParseConditionalExpr"); | 11041 TRACE_PARSER("ParseConditionalExpr"); |
11563 const TokenPosition expr_pos = TokenPos(); | 11042 const TokenPosition expr_pos = TokenPos(); |
11564 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); | 11043 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); |
11565 if (CurrentToken() == Token::kCONDITIONAL) { | 11044 if (CurrentToken() == Token::kCONDITIONAL) { |
11566 EnsureExpressionTemp(); | 11045 EnsureExpressionTemp(); |
11567 ConsumeToken(); | 11046 ConsumeToken(); |
11568 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 11047 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
11569 ExpectToken(Token::kCOLON); | 11048 ExpectToken(Token::kCOLON); |
11570 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 11049 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
11571 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 11050 expr = new (Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
11572 } | 11051 } |
11573 return expr; | 11052 return expr; |
11574 } | 11053 } |
11575 | 11054 |
11576 | 11055 |
11577 AstNode* Parser::ParseUnaryExpr() { | 11056 AstNode* Parser::ParseUnaryExpr() { |
11578 TRACE_PARSER("ParseUnaryExpr"); | 11057 TRACE_PARSER("ParseUnaryExpr"); |
11579 AstNode* expr = NULL; | 11058 AstNode* expr = NULL; |
11580 const TokenPosition op_pos = TokenPos(); | 11059 const TokenPosition op_pos = TokenPos(); |
11581 if (IsAwaitKeyword()) { | 11060 if (IsAwaitKeyword()) { |
11582 TRACE_PARSER("ParseAwaitExpr"); | 11061 TRACE_PARSER("ParseAwaitExpr"); |
11583 if (!innermost_function().IsAsyncFunction() && | 11062 if (!innermost_function().IsAsyncFunction() && |
11584 !innermost_function().IsAsyncClosure() && | 11063 !innermost_function().IsAsyncClosure() && |
11585 !innermost_function().IsAsyncGenerator() && | 11064 !innermost_function().IsAsyncGenerator() && |
11586 !innermost_function().IsAsyncGenClosure()) { | 11065 !innermost_function().IsAsyncGenClosure()) { |
11587 ReportError("await operator is only allowed in an asynchronous function"); | 11066 ReportError("await operator is only allowed in an asynchronous function"); |
11588 } | 11067 } |
11589 ConsumeToken(); | 11068 ConsumeToken(); |
11590 parsed_function()->record_await(); | 11069 parsed_function()->record_await(); |
11591 | 11070 |
11592 LocalVariable* saved_try_ctx; | 11071 LocalVariable* saved_try_ctx; |
11593 LocalVariable* async_saved_try_ctx; | 11072 LocalVariable* async_saved_try_ctx; |
11594 LocalVariable* outer_saved_try_ctx; | 11073 LocalVariable* outer_saved_try_ctx; |
11595 LocalVariable* outer_async_saved_try_ctx; | 11074 LocalVariable* outer_async_saved_try_ctx; |
11596 CheckAsyncOpInTryBlock(&saved_try_ctx, | 11075 CheckAsyncOpInTryBlock(&saved_try_ctx, &async_saved_try_ctx, |
11597 &async_saved_try_ctx, | 11076 &outer_saved_try_ctx, &outer_async_saved_try_ctx); |
11598 &outer_saved_try_ctx, | 11077 expr = new (Z) AwaitNode(op_pos, ParseUnaryExpr(), saved_try_ctx, |
11599 &outer_async_saved_try_ctx); | 11078 async_saved_try_ctx, outer_saved_try_ctx, |
11600 expr = new (Z) AwaitNode(op_pos, | 11079 outer_async_saved_try_ctx, current_block_->scope); |
11601 ParseUnaryExpr(), | |
11602 saved_try_ctx, | |
11603 async_saved_try_ctx, | |
11604 outer_saved_try_ctx, | |
11605 outer_async_saved_try_ctx, | |
11606 current_block_->scope); | |
11607 } else if (IsPrefixOperator(CurrentToken())) { | 11080 } else if (IsPrefixOperator(CurrentToken())) { |
11608 Token::Kind unary_op = CurrentToken(); | 11081 Token::Kind unary_op = CurrentToken(); |
11609 if (unary_op == Token::kSUB) { | 11082 if (unary_op == Token::kSUB) { |
11610 unary_op = Token::kNEGATE; | 11083 unary_op = Token::kNEGATE; |
11611 } | 11084 } |
11612 ConsumeToken(); | 11085 ConsumeToken(); |
11613 expr = ParseUnaryExpr(); | 11086 expr = ParseUnaryExpr(); |
11614 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { | 11087 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { |
11615 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); | 11088 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); |
11616 } else { | 11089 } else { |
11617 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 11090 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
11618 } | 11091 } |
11619 } else if (IsIncrementOperator(CurrentToken())) { | 11092 } else if (IsIncrementOperator(CurrentToken())) { |
11620 Token::Kind incr_op = CurrentToken(); | 11093 Token::Kind incr_op = CurrentToken(); |
11621 ConsumeToken(); | 11094 ConsumeToken(); |
11622 String* expr_ident = | 11095 String* expr_ident = |
11623 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11096 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11624 const TokenPosition expr_pos = TokenPos(); | 11097 const TokenPosition expr_pos = TokenPos(); |
11625 expr = ParseUnaryExpr(); | 11098 expr = ParseUnaryExpr(); |
11626 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11099 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
11627 ReportError(expr_pos, "expression is not assignable"); | 11100 ReportError(expr_pos, "expression is not assignable"); |
11628 } | 11101 } |
11629 // Is prefix. | 11102 // Is prefix. |
11630 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11103 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
11631 Token::Kind binary_op = | 11104 Token::Kind binary_op = |
11632 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 11105 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
11633 BinaryOpNode* add = new(Z) BinaryOpNode( | 11106 BinaryOpNode* add = new (Z) BinaryOpNode( |
11634 op_pos, | 11107 op_pos, binary_op, expr, |
11635 binary_op, | 11108 new (Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
11636 expr, | |
11637 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); | |
11638 AstNode* store = | 11109 AstNode* store = |
11639 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); | 11110 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); |
11640 ASSERT(store != NULL); | 11111 ASSERT(store != NULL); |
11641 let_expr->AddNode(store); | 11112 let_expr->AddNode(store); |
11642 expr = let_expr; | 11113 expr = let_expr; |
11643 } else { | 11114 } else { |
11644 expr = ParsePostfixExpr(); | 11115 expr = ParsePostfixExpr(); |
11645 } | 11116 } |
11646 return expr; | 11117 return expr; |
11647 } | 11118 } |
11648 | 11119 |
11649 | 11120 |
11650 ArgumentListNode* Parser::ParseActualParameters( | 11121 ArgumentListNode* Parser::ParseActualParameters( |
11651 ArgumentListNode* implicit_arguments, | 11122 ArgumentListNode* implicit_arguments, |
11652 bool require_const) { | 11123 bool require_const) { |
11653 TRACE_PARSER("ParseActualParameters"); | 11124 TRACE_PARSER("ParseActualParameters"); |
11654 ASSERT(CurrentToken() == Token::kLPAREN); | 11125 ASSERT(CurrentToken() == Token::kLPAREN); |
11655 const bool saved_mode = SetAllowFunctionLiterals(true); | 11126 const bool saved_mode = SetAllowFunctionLiterals(true); |
11656 ArgumentListNode* arguments; | 11127 ArgumentListNode* arguments; |
11657 if (implicit_arguments == NULL) { | 11128 if (implicit_arguments == NULL) { |
11658 arguments = new(Z) ArgumentListNode(TokenPos()); | 11129 arguments = new (Z) ArgumentListNode(TokenPos()); |
11659 } else { | 11130 } else { |
11660 arguments = implicit_arguments; | 11131 arguments = implicit_arguments; |
11661 } | 11132 } |
11662 const GrowableObjectArray& names = | 11133 const GrowableObjectArray& names = |
11663 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 11134 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
11664 bool named_argument_seen = false; | 11135 bool named_argument_seen = false; |
11665 if (LookaheadToken(1) != Token::kRPAREN) { | 11136 if (LookaheadToken(1) != Token::kRPAREN) { |
11666 String& arg_name = String::Handle(Z); | 11137 String& arg_name = String::Handle(Z); |
11667 do { | 11138 do { |
11668 ASSERT((CurrentToken() == Token::kLPAREN) || | 11139 ASSERT((CurrentToken() == Token::kLPAREN) || |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11705 | 11176 |
11706 | 11177 |
11707 AstNode* Parser::ParseStaticCall(const Class& cls, | 11178 AstNode* Parser::ParseStaticCall(const Class& cls, |
11708 const String& func_name, | 11179 const String& func_name, |
11709 TokenPosition ident_pos) { | 11180 TokenPosition ident_pos) { |
11710 TRACE_PARSER("ParseStaticCall"); | 11181 TRACE_PARSER("ParseStaticCall"); |
11711 const TokenPosition call_pos = TokenPos(); | 11182 const TokenPosition call_pos = TokenPos(); |
11712 ASSERT(CurrentToken() == Token::kLPAREN); | 11183 ASSERT(CurrentToken() == Token::kLPAREN); |
11713 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11184 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11714 const int num_arguments = arguments->length(); | 11185 const int num_arguments = arguments->length(); |
11715 const Function& func = Function::ZoneHandle(Z, | 11186 const Function& func = Function::ZoneHandle( |
11716 Resolver::ResolveStatic(cls, | 11187 Z, Resolver::ResolveStatic(cls, func_name, num_arguments, |
11717 func_name, | 11188 arguments->names())); |
11718 num_arguments, | |
11719 arguments->names())); | |
11720 if (func.IsNull()) { | 11189 if (func.IsNull()) { |
11721 // Check if there is a static field of the same name, it could be a closure | 11190 // Check if there is a static field of the same name, it could be a closure |
11722 // and so we try and invoke the closure. | 11191 // and so we try and invoke the closure. |
11723 AstNode* closure = NULL; | 11192 AstNode* closure = NULL; |
11724 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(func_name)); | 11193 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(func_name)); |
11725 Function& func = Function::ZoneHandle(Z); | 11194 Function& func = Function::ZoneHandle(Z); |
11726 if (field.IsNull()) { | 11195 if (field.IsNull()) { |
11727 // No field, check if we have an explicit getter function. | 11196 // No field, check if we have an explicit getter function. |
11728 const String& getter_name = | 11197 const String& getter_name = |
11729 String::ZoneHandle(Z, Field::GetterName(func_name)); | 11198 String::ZoneHandle(Z, Field::GetterName(func_name)); |
11730 const int kNumArguments = 0; // no arguments. | 11199 const int kNumArguments = 0; // no arguments. |
11731 func = Resolver::ResolveStatic(cls, | 11200 func = Resolver::ResolveStatic(cls, getter_name, kNumArguments, |
11732 getter_name, | |
11733 kNumArguments, | |
11734 Object::empty_array()); | 11201 Object::empty_array()); |
11735 if (!func.IsNull()) { | 11202 if (!func.IsNull()) { |
11736 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 11203 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
11737 closure = new(Z) StaticGetterNode( | 11204 closure = new (Z) StaticGetterNode( |
11738 call_pos, | 11205 call_pos, NULL, Class::ZoneHandle(Z, cls.raw()), func_name); |
11739 NULL, | |
11740 Class::ZoneHandle(Z, cls.raw()), | |
11741 func_name); | |
11742 return BuildClosureCall(call_pos, closure, arguments); | 11206 return BuildClosureCall(call_pos, closure, arguments); |
11743 } | 11207 } |
11744 } else { | 11208 } else { |
11745 closure = GenerateStaticFieldLookup(field, call_pos); | 11209 closure = GenerateStaticFieldLookup(field, call_pos); |
11746 return BuildClosureCall(call_pos, closure, arguments); | 11210 return BuildClosureCall(call_pos, closure, arguments); |
11747 } | 11211 } |
11748 // Could not resolve static method: throw a NoSuchMethodError. | 11212 // Could not resolve static method: throw a NoSuchMethodError. |
11749 return ThrowNoSuchMethodError(ident_pos, | 11213 return ThrowNoSuchMethodError(ident_pos, cls, func_name, arguments, |
11750 cls, | |
11751 func_name, | |
11752 arguments, | |
11753 InvocationMirror::kStatic, | 11214 InvocationMirror::kStatic, |
11754 InvocationMirror::kMethod, | 11215 InvocationMirror::kMethod, |
11755 NULL); // No existing function. | 11216 NULL); // No existing function. |
11756 } else if (cls.IsTopLevel() && | 11217 } else if (cls.IsTopLevel() && (cls.library() == Library::CoreLibrary()) && |
11757 (cls.library() == Library::CoreLibrary()) && | 11218 (func.name() == Symbols::Identical().raw())) { |
11758 (func.name() == Symbols::Identical().raw())) { | |
11759 // This is the predefined toplevel function identical(a,b). | 11219 // This is the predefined toplevel function identical(a,b). |
11760 // Create a comparison node instead of a static call to the function. | 11220 // Create a comparison node instead of a static call to the function. |
11761 ASSERT(num_arguments == 2); | 11221 ASSERT(num_arguments == 2); |
11762 | 11222 |
11763 // If both arguments are constant expressions of type string, | 11223 // If both arguments are constant expressions of type string, |
11764 // evaluate and canonicalize them. | 11224 // evaluate and canonicalize them. |
11765 // This guarantees that identical("ab", "a"+"b") is true. | 11225 // This guarantees that identical("ab", "a"+"b") is true. |
11766 // An alternative way to guarantee this would be to introduce | 11226 // An alternative way to guarantee this would be to introduce |
11767 // an AST node that canonicalizes a value. | 11227 // an AST node that canonicalizes a value. |
11768 AstNode* arg0 = arguments->NodeAt(0); | 11228 AstNode* arg0 = arguments->NodeAt(0); |
11769 const Instance* val0 = arg0->EvalConstExpr(); | 11229 const Instance* val0 = arg0->EvalConstExpr(); |
11770 if ((val0 != NULL) && (val0->IsString())) { | 11230 if ((val0 != NULL) && (val0->IsString())) { |
11771 AstNode* arg1 = arguments->NodeAt(1); | 11231 AstNode* arg1 = arguments->NodeAt(1); |
11772 const Instance* val1 = arg1->EvalConstExpr(); | 11232 const Instance* val1 = arg1->EvalConstExpr(); |
11773 if ((val1 != NULL) && (val1->IsString())) { | 11233 if ((val1 != NULL) && (val1->IsString())) { |
11774 arguments->SetNodeAt(0, | 11234 arguments->SetNodeAt( |
11775 new(Z) LiteralNode(arg0->token_pos(), | 11235 0, new (Z) LiteralNode(arg0->token_pos(), |
11776 EvaluateConstExpr(arg0->token_pos(), arg0))); | 11236 EvaluateConstExpr(arg0->token_pos(), arg0))); |
11777 arguments->SetNodeAt(1, | 11237 arguments->SetNodeAt( |
11778 new(Z) LiteralNode(arg1->token_pos(), | 11238 1, new (Z) LiteralNode(arg1->token_pos(), |
11779 EvaluateConstExpr(arg1->token_pos(), arg1))); | 11239 EvaluateConstExpr(arg1->token_pos(), arg1))); |
11780 } | 11240 } |
11781 } | 11241 } |
11782 return new(Z) ComparisonNode(ident_pos, | 11242 return new (Z) ComparisonNode(ident_pos, Token::kEQ_STRICT, |
11783 Token::kEQ_STRICT, | 11243 arguments->NodeAt(0), arguments->NodeAt(1)); |
11784 arguments->NodeAt(0), | |
11785 arguments->NodeAt(1)); | |
11786 } | 11244 } |
11787 return new(Z) StaticCallNode(ident_pos, func, arguments); | 11245 return new (Z) StaticCallNode(ident_pos, func, arguments); |
11788 } | 11246 } |
11789 | 11247 |
11790 | 11248 |
11791 AstNode* Parser::ParseInstanceCall(AstNode* receiver, | 11249 AstNode* Parser::ParseInstanceCall(AstNode* receiver, |
11792 const String& func_name, | 11250 const String& func_name, |
11793 TokenPosition ident_pos, | 11251 TokenPosition ident_pos, |
11794 bool is_conditional) { | 11252 bool is_conditional) { |
11795 TRACE_PARSER("ParseInstanceCall"); | 11253 TRACE_PARSER("ParseInstanceCall"); |
11796 CheckToken(Token::kLPAREN); | 11254 CheckToken(Token::kLPAREN); |
11797 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11255 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11798 return new(Z) InstanceCallNode(ident_pos, | 11256 return new (Z) InstanceCallNode(ident_pos, receiver, func_name, arguments, |
11799 receiver, | 11257 is_conditional); |
11800 func_name, | |
11801 arguments, | |
11802 is_conditional); | |
11803 } | 11258 } |
11804 | 11259 |
11805 | 11260 |
11806 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 11261 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
11807 TRACE_PARSER("ParseClosureCall"); | 11262 TRACE_PARSER("ParseClosureCall"); |
11808 const TokenPosition call_pos = TokenPos(); | 11263 const TokenPosition call_pos = TokenPos(); |
11809 ASSERT(CurrentToken() == Token::kLPAREN); | 11264 ASSERT(CurrentToken() == Token::kLPAREN); |
11810 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11265 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11811 return BuildClosureCall(call_pos, closure, arguments); | 11266 return BuildClosureCall(call_pos, closure, arguments); |
11812 } | 11267 } |
11813 | 11268 |
11814 | 11269 |
11815 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 11270 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
11816 TokenPosition ident_pos) { | 11271 TokenPosition ident_pos) { |
11817 // If the static field has an initializer, initialize the field at compile | 11272 // If the static field has an initializer, initialize the field at compile |
11818 // time, which is only possible if the field is const. | 11273 // time, which is only possible if the field is const. |
11819 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 11274 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
11820 if (initializing_getter != NULL) { | 11275 if (initializing_getter != NULL) { |
11821 // The field is not yet initialized and could not be initialized at compile | 11276 // The field is not yet initialized and could not be initialized at compile |
11822 // time. The getter will initialize the field. | 11277 // time. The getter will initialize the field. |
11823 return initializing_getter; | 11278 return initializing_getter; |
11824 } | 11279 } |
11825 // The field is initialized. | 11280 // The field is initialized. |
11826 ASSERT(field.is_static()); | 11281 ASSERT(field.is_static()); |
11827 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); | 11282 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); |
11828 const String& field_name = String::ZoneHandle(Z, field.name()); | 11283 const String& field_name = String::ZoneHandle(Z, field.name()); |
11829 const String& getter_name = | 11284 const String& getter_name = |
11830 String::Handle(Z, Field::GetterSymbol(field_name)); | 11285 String::Handle(Z, Field::GetterSymbol(field_name)); |
11831 const Function& getter = Function::Handle(Z, | 11286 const Function& getter = |
11832 field_owner.LookupStaticFunction(getter_name)); | 11287 Function::Handle(Z, field_owner.LookupStaticFunction(getter_name)); |
11833 // Never load field directly if there is a getter (deterministic AST). | 11288 // Never load field directly if there is a getter (deterministic AST). |
11834 if (getter.IsNull() || field.is_const()) { | 11289 if (getter.IsNull() || field.is_const()) { |
11835 return new(Z) LoadStaticFieldNode( | 11290 return new (Z) |
11836 ident_pos, Field::ZoneHandle(Z, field.raw())); | 11291 LoadStaticFieldNode(ident_pos, Field::ZoneHandle(Z, field.raw())); |
11837 } else { | 11292 } else { |
11838 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); | 11293 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); |
11839 return new(Z) StaticGetterNode(ident_pos, | 11294 return new (Z) StaticGetterNode(ident_pos, |
11840 NULL, // Receiver. | 11295 NULL, // Receiver. |
11841 field_owner, | 11296 field_owner, field_name); |
11842 field_name); | |
11843 } | 11297 } |
11844 } | 11298 } |
11845 | 11299 |
11846 | 11300 |
11847 // Reference to 'field_name' with explicit class as primary. | 11301 // Reference to 'field_name' with explicit class as primary. |
11848 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, | 11302 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, |
11849 const String& field_name, | 11303 const String& field_name, |
11850 TokenPosition ident_pos) { | 11304 TokenPosition ident_pos) { |
11851 AstNode* access = NULL; | 11305 AstNode* access = NULL; |
11852 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); | 11306 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); |
11853 Function& func = Function::ZoneHandle(Z); | 11307 Function& func = Function::ZoneHandle(Z); |
11854 if (field.IsNull()) { | 11308 if (field.IsNull()) { |
11855 // No field, check if we have an explicit getter function. | 11309 // No field, check if we have an explicit getter function. |
11856 func = cls.LookupGetterFunction(field_name); | 11310 func = cls.LookupGetterFunction(field_name); |
11857 if (func.IsNull() || func.IsDynamicFunction()) { | 11311 if (func.IsNull() || func.IsDynamicFunction()) { |
11858 // We might be referring to an implicit closure, check to see if | 11312 // We might be referring to an implicit closure, check to see if |
11859 // there is a function of the same name. | 11313 // there is a function of the same name. |
11860 func = cls.LookupStaticFunction(field_name); | 11314 func = cls.LookupStaticFunction(field_name); |
11861 if (!func.IsNull()) { | 11315 if (!func.IsNull()) { |
11862 access = CreateImplicitClosureNode(func, ident_pos, NULL); | 11316 access = CreateImplicitClosureNode(func, ident_pos, NULL); |
11863 } else { | 11317 } else { |
11864 // No function to closurize found found. | 11318 // No function to closurize found found. |
11865 // This field access may turn out to be a call to the setter. | 11319 // This field access may turn out to be a call to the setter. |
11866 // Create a getter call, which may later be turned into | 11320 // Create a getter call, which may later be turned into |
11867 // a setter call, or else the backend will generate | 11321 // a setter call, or else the backend will generate |
11868 // a throw NoSuchMethodError(). | 11322 // a throw NoSuchMethodError(). |
11869 access = new(Z) StaticGetterNode(ident_pos, | 11323 access = new (Z) StaticGetterNode( |
11870 NULL, | 11324 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), field_name); |
11871 Class::ZoneHandle(Z, cls.raw()), | |
11872 field_name); | |
11873 } | 11325 } |
11874 } else { | 11326 } else { |
11875 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 11327 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
11876 access = new(Z) StaticGetterNode( | 11328 access = new (Z) StaticGetterNode( |
11877 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), field_name); | 11329 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), field_name); |
11878 } | 11330 } |
11879 } else { | 11331 } else { |
11880 access = GenerateStaticFieldLookup(field, ident_pos); | 11332 access = GenerateStaticFieldLookup(field, ident_pos); |
11881 } | 11333 } |
11882 return access; | 11334 return access; |
11883 } | 11335 } |
11884 | 11336 |
11885 | 11337 |
11886 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 11338 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
11887 if (!node->IsPrimaryNode()) { | 11339 if (!node->IsPrimaryNode()) { |
11888 return node; | 11340 return node; |
11889 } | 11341 } |
11890 PrimaryNode* primary = node->AsPrimaryNode(); | 11342 PrimaryNode* primary = node->AsPrimaryNode(); |
11891 if (primary->primary().IsString()) { | 11343 if (primary->primary().IsString()) { |
11892 if (primary->IsSuper()) { | 11344 if (primary->IsSuper()) { |
11893 return primary; | 11345 return primary; |
11894 } | 11346 } |
11895 // In a static method, evaluation of an unresolved identifier causes a | 11347 // In a static method, evaluation of an unresolved identifier causes a |
11896 // NoSuchMethodError to be thrown. | 11348 // NoSuchMethodError to be thrown. |
11897 // In an instance method, we convert this into a getter call | 11349 // In an instance method, we convert this into a getter call |
11898 // for a field (which may be defined in a subclass.) | 11350 // for a field (which may be defined in a subclass.) |
11899 const String& name = | 11351 const String& name = |
11900 String::Cast(Object::ZoneHandle(primary->primary().raw())); | 11352 String::Cast(Object::ZoneHandle(primary->primary().raw())); |
11901 if (current_function().is_static() || | 11353 if (current_function().is_static() || |
11902 current_function().IsInFactoryScope()) { | 11354 current_function().IsInFactoryScope()) { |
11903 StaticGetterNode* getter = new(Z) StaticGetterNode( | 11355 StaticGetterNode* getter = new (Z) |
11904 primary->token_pos(), | 11356 StaticGetterNode(primary->token_pos(), |
11905 NULL, // No receiver. | 11357 NULL, // No receiver. |
11906 Class::ZoneHandle(Z, current_class().raw()), | 11358 Class::ZoneHandle(Z, current_class().raw()), name); |
11907 name); | |
11908 getter->set_is_deferred(primary->is_deferred_reference()); | 11359 getter->set_is_deferred(primary->is_deferred_reference()); |
11909 return getter; | 11360 return getter; |
11910 } else { | 11361 } else { |
11911 AstNode* receiver = LoadReceiver(primary->token_pos()); | 11362 AstNode* receiver = LoadReceiver(primary->token_pos()); |
11912 return CallGetter(node->token_pos(), receiver, name); | 11363 return CallGetter(node->token_pos(), receiver, name); |
11913 } | 11364 } |
11914 } | 11365 } |
11915 return primary; | 11366 return primary; |
11916 } | 11367 } |
11917 | 11368 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11957 } | 11408 } |
11958 // TODO(regis): Verify that CaptureInstantiator() was already called | 11409 // TODO(regis): Verify that CaptureInstantiator() was already called |
11959 // and remove call below. | 11410 // and remove call below. |
11960 if (FunctionLevel() > 0) { | 11411 if (FunctionLevel() > 0) { |
11961 // Make sure that the class instantiator is captured. | 11412 // Make sure that the class instantiator is captured. |
11962 CaptureInstantiator(); | 11413 CaptureInstantiator(); |
11963 } | 11414 } |
11964 type_parameter ^= ClassFinalizer::FinalizeType( | 11415 type_parameter ^= ClassFinalizer::FinalizeType( |
11965 current_class(), type_parameter, ClassFinalizer::kCanonicalize); | 11416 current_class(), type_parameter, ClassFinalizer::kCanonicalize); |
11966 ASSERT(!type_parameter.IsMalformed()); | 11417 ASSERT(!type_parameter.IsMalformed()); |
11967 return new(Z) TypeNode(primary_pos, type_parameter); | 11418 return new (Z) TypeNode(primary_pos, type_parameter); |
11968 } else { | 11419 } else { |
11969 ASSERT(type_parameter.IsFunctionTypeParameter()); | 11420 ASSERT(type_parameter.IsFunctionTypeParameter()); |
11970 // TODO(regis): Verify that CaptureFunctionInstantiator() was already | 11421 // TODO(regis): Verify that CaptureFunctionInstantiator() was already |
11971 // called if necessary. | 11422 // called if necessary. |
11972 // TODO(regis): Finalize type parameter and return as type node. | 11423 // TODO(regis): Finalize type parameter and return as type node. |
11973 // For now, map to dynamic type. | 11424 // For now, map to dynamic type. |
11974 Type& type = Type::ZoneHandle(Z, Type::DynamicType()); | 11425 Type& type = Type::ZoneHandle(Z, Type::DynamicType()); |
11975 return new(Z) TypeNode(primary_pos, type); | 11426 return new (Z) TypeNode(primary_pos, type); |
11976 } | 11427 } |
11977 } | 11428 } |
11978 | 11429 |
11979 | 11430 |
11980 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 11431 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
11981 AstNode* left = primary; | 11432 AstNode* left = primary; |
11982 while (true) { | 11433 while (true) { |
11983 AstNode* selector = NULL; | 11434 AstNode* selector = NULL; |
11984 if ((CurrentToken() == Token::kPERIOD) || | 11435 if ((CurrentToken() == Token::kPERIOD) || |
11985 (CurrentToken() == Token::kQM_PERIOD)) { | 11436 (CurrentToken() == Token::kQM_PERIOD)) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12029 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11480 PrimaryNode* primary_node = left->AsPrimaryNode(); |
12030 if (primary_node->primary().IsClass()) { | 11481 if (primary_node->primary().IsClass()) { |
12031 // If the primary node referred to a class we are loading a | 11482 // If the primary node referred to a class we are loading a |
12032 // qualified static field. | 11483 // qualified static field. |
12033 cls ^= primary_node->primary().raw(); | 11484 cls ^= primary_node->primary().raw(); |
12034 is_deferred = primary_node->is_deferred_reference(); | 11485 is_deferred = primary_node->is_deferred_reference(); |
12035 } | 11486 } |
12036 } | 11487 } |
12037 if (cls.IsNull()) { | 11488 if (cls.IsNull()) { |
12038 // Instance field access. | 11489 // Instance field access. |
12039 selector = new(Z) InstanceGetterNode(ident_pos, | 11490 selector = new (Z) |
12040 left, | 11491 InstanceGetterNode(ident_pos, left, *ident, is_conditional); |
12041 *ident, | |
12042 is_conditional); | |
12043 } else { | 11492 } else { |
12044 // Static field access. | 11493 // Static field access. |
12045 selector = GenerateStaticFieldAccess(cls, *ident, ident_pos); | 11494 selector = GenerateStaticFieldAccess(cls, *ident, ident_pos); |
12046 ASSERT(selector != NULL); | 11495 ASSERT(selector != NULL); |
12047 if (selector->IsLoadStaticFieldNode()) { | 11496 if (selector->IsLoadStaticFieldNode()) { |
12048 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 11497 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
12049 } else if (selector->IsStaticGetterNode()) { | 11498 } else if (selector->IsStaticGetterNode()) { |
12050 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); | 11499 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); |
12051 } | 11500 } |
12052 } | 11501 } |
(...skipping 10 matching lines...) Expand all Loading... |
12063 SetAllowFunctionLiterals(saved_mode); | 11512 SetAllowFunctionLiterals(saved_mode); |
12064 ExpectToken(Token::kRBRACK); | 11513 ExpectToken(Token::kRBRACK); |
12065 AstNode* array = left; | 11514 AstNode* array = left; |
12066 if (left->IsPrimaryNode()) { | 11515 if (left->IsPrimaryNode()) { |
12067 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11516 PrimaryNode* primary_node = left->AsPrimaryNode(); |
12068 const TokenPosition primary_pos = primary_node->token_pos(); | 11517 const TokenPosition primary_pos = primary_node->token_pos(); |
12069 if (primary_node->primary().IsFunction()) { | 11518 if (primary_node->primary().IsFunction()) { |
12070 array = LoadClosure(primary_node); | 11519 array = LoadClosure(primary_node); |
12071 } else if (primary_node->primary().IsClass()) { | 11520 } else if (primary_node->primary().IsClass()) { |
12072 const Class& type_class = Class::Cast(primary_node->primary()); | 11521 const Class& type_class = Class::Cast(primary_node->primary()); |
12073 AbstractType& type = Type::ZoneHandle(Z, | 11522 AbstractType& type = Type::ZoneHandle( |
12074 Type::New(type_class, TypeArguments::Handle(Z), | 11523 Z, Type::New(type_class, TypeArguments::Handle(Z), primary_pos, |
12075 primary_pos, Heap::kOld)); | 11524 Heap::kOld)); |
12076 type ^= ClassFinalizer::FinalizeType( | 11525 type ^= ClassFinalizer::FinalizeType(current_class(), type, |
12077 current_class(), type, ClassFinalizer::kCanonicalize); | 11526 ClassFinalizer::kCanonicalize); |
12078 // Type may be malbounded, but not malformed. | 11527 // Type may be malbounded, but not malformed. |
12079 ASSERT(!type.IsMalformed()); | 11528 ASSERT(!type.IsMalformed()); |
12080 array = new(Z) TypeNode(primary_pos, type); | 11529 array = new (Z) TypeNode(primary_pos, type); |
12081 } else if (primary_node->primary().IsTypeParameter()) { | 11530 } else if (primary_node->primary().IsTypeParameter()) { |
12082 array = LoadTypeParameter(primary_node); | 11531 array = LoadTypeParameter(primary_node); |
12083 } else { | 11532 } else { |
12084 UNREACHABLE(); // Internal parser error. | 11533 UNREACHABLE(); // Internal parser error. |
12085 } | 11534 } |
12086 } | 11535 } |
12087 selector = new(Z) LoadIndexedNode( | 11536 selector = new (Z) |
12088 bracket_pos, array, index, Class::ZoneHandle(Z)); | 11537 LoadIndexedNode(bracket_pos, array, index, Class::ZoneHandle(Z)); |
12089 } else if (IsArgumentPart()) { | 11538 } else if (IsArgumentPart()) { |
12090 if (CurrentToken() == Token::kLT) { | 11539 if (CurrentToken() == Token::kLT) { |
12091 // Type arguments. | 11540 // Type arguments. |
12092 if (!FLAG_generic_method_syntax) { | 11541 if (!FLAG_generic_method_syntax) { |
12093 ReportError("generic type arguments not supported."); | 11542 ReportError("generic type arguments not supported."); |
12094 } | 11543 } |
12095 // TODO(regis): Pass type arguments in generic call. | 11544 // TODO(regis): Pass type arguments in generic call. |
12096 // For now, resolve type arguments and ignore. | 11545 // For now, resolve type arguments and ignore. |
12097 ParseTypeArguments(ClassFinalizer::kCanonicalize); | 11546 ParseTypeArguments(ClassFinalizer::kCanonicalize); |
12098 } | 11547 } |
12099 if (left->IsPrimaryNode()) { | 11548 if (left->IsPrimaryNode()) { |
12100 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11549 PrimaryNode* primary_node = left->AsPrimaryNode(); |
12101 const TokenPosition primary_pos = primary_node->token_pos(); | 11550 const TokenPosition primary_pos = primary_node->token_pos(); |
12102 if (primary_node->primary().IsFunction()) { | 11551 if (primary_node->primary().IsFunction()) { |
12103 const Function& func = Function::Cast(primary_node->primary()); | 11552 const Function& func = Function::Cast(primary_node->primary()); |
12104 const String& func_name = String::ZoneHandle(Z, func.name()); | 11553 const String& func_name = String::ZoneHandle(Z, func.name()); |
12105 if (func.is_static()) { | 11554 if (func.is_static()) { |
12106 // Parse static function call. | 11555 // Parse static function call. |
12107 Class& cls = Class::Handle(Z, func.Owner()); | 11556 Class& cls = Class::Handle(Z, func.Owner()); |
12108 selector = ParseStaticCall(cls, func_name, primary_pos); | 11557 selector = ParseStaticCall(cls, func_name, primary_pos); |
12109 } else { | 11558 } else { |
12110 // Dynamic function call on implicit "this" parameter. | 11559 // Dynamic function call on implicit "this" parameter. |
12111 if (current_function().is_static()) { | 11560 if (current_function().is_static()) { |
12112 ReportError(primary_pos, | 11561 ReportError(primary_pos, |
12113 "cannot access instance method '%s' " | 11562 "cannot access instance method '%s' " |
12114 "from static function", | 11563 "from static function", |
12115 func_name.ToCString()); | 11564 func_name.ToCString()); |
12116 } | 11565 } |
12117 selector = ParseInstanceCall(LoadReceiver(primary_pos), | 11566 selector = |
12118 func_name, | 11567 ParseInstanceCall(LoadReceiver(primary_pos), func_name, |
12119 primary_pos, | 11568 primary_pos, false /* is_conditional */); |
12120 false /* is_conditional */); | |
12121 } | 11569 } |
12122 } else if (primary_node->primary().IsString()) { | 11570 } else if (primary_node->primary().IsString()) { |
12123 // Primary is an unresolved name. | 11571 // Primary is an unresolved name. |
12124 if (primary_node->IsSuper()) { | 11572 if (primary_node->IsSuper()) { |
12125 ReportError(primary_pos, "illegal use of super"); | 11573 ReportError(primary_pos, "illegal use of super"); |
12126 } | 11574 } |
12127 const String& name = | 11575 const String& name = |
12128 String::Cast(Object::ZoneHandle(primary_node->primary().raw())); | 11576 String::Cast(Object::ZoneHandle(primary_node->primary().raw())); |
12129 if (current_function().is_static()) { | 11577 if (current_function().is_static()) { |
12130 // The static call will be converted to throwing a NSM error. | 11578 // The static call will be converted to throwing a NSM error. |
12131 selector = ParseStaticCall(current_class(), name, primary_pos); | 11579 selector = ParseStaticCall(current_class(), name, primary_pos); |
12132 } else { | 11580 } else { |
12133 // Treat as call to unresolved (instance) method. | 11581 // Treat as call to unresolved (instance) method. |
12134 selector = ParseInstanceCall(LoadReceiver(primary_pos), | 11582 selector = |
12135 name, | 11583 ParseInstanceCall(LoadReceiver(primary_pos), name, primary_pos, |
12136 primary_pos, | 11584 false /* is_conditional */); |
12137 false /* is_conditional */); | |
12138 } | 11585 } |
12139 } else if (primary_node->primary().IsTypeParameter()) { | 11586 } else if (primary_node->primary().IsTypeParameter()) { |
12140 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | 11587 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
12141 type_parameter = TypeParameter::Cast(primary_node->primary()).raw(); | 11588 type_parameter = TypeParameter::Cast(primary_node->primary()).raw(); |
12142 const String& name = String::ZoneHandle(Z, type_parameter.name()); | 11589 const String& name = String::ZoneHandle(Z, type_parameter.name()); |
12143 if (type_parameter.IsClassTypeParameter()) { | 11590 if (type_parameter.IsClassTypeParameter()) { |
12144 if (ParsingStaticMember()) { | 11591 if (ParsingStaticMember()) { |
12145 // Treat as this.T(), because T is in scope. | 11592 // Treat as this.T(), because T is in scope. |
12146 ReportError(primary_pos, | 11593 ReportError(primary_pos, |
12147 "cannot access type parameter '%s' " | 11594 "cannot access type parameter '%s' " |
12148 "from static function", | 11595 "from static function", |
12149 name.ToCString()); | 11596 name.ToCString()); |
12150 } else { | 11597 } else { |
12151 // Treat as call to unresolved (instance) method. | 11598 // Treat as call to unresolved (instance) method. |
12152 selector = ParseInstanceCall(LoadReceiver(primary_pos), | 11599 selector = |
12153 name, | 11600 ParseInstanceCall(LoadReceiver(primary_pos), name, |
12154 primary_pos, | 11601 primary_pos, false /* is_conditional */); |
12155 false /* is_conditional */); | |
12156 } | 11602 } |
12157 } else { | 11603 } else { |
12158 ASSERT(type_parameter.IsFunctionTypeParameter()); | 11604 ASSERT(type_parameter.IsFunctionTypeParameter()); |
12159 // TODO(regis): Should we throw a type error instead? | 11605 // TODO(regis): Should we throw a type error instead? |
12160 ReportError(primary_pos, | 11606 ReportError(primary_pos, |
12161 "illegal use of function type parameter '%s'", | 11607 "illegal use of function type parameter '%s'", |
12162 name.ToCString()); | 11608 name.ToCString()); |
12163 } | 11609 } |
12164 } else if (primary_node->primary().IsClass()) { | 11610 } else if (primary_node->primary().IsClass()) { |
12165 const Class& type_class = Class::Cast(primary_node->primary()); | 11611 const Class& type_class = Class::Cast(primary_node->primary()); |
12166 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 11612 AbstractType& type = Type::ZoneHandle( |
12167 type_class, TypeArguments::Handle(Z), primary_pos, Heap::kOld)); | 11613 Z, Type::New(type_class, TypeArguments::Handle(Z), primary_pos, |
12168 type ^= ClassFinalizer::FinalizeType( | 11614 Heap::kOld)); |
12169 current_class(), type, ClassFinalizer::kCanonicalize); | 11615 type ^= ClassFinalizer::FinalizeType(current_class(), type, |
| 11616 ClassFinalizer::kCanonicalize); |
12170 // Type may be malbounded, but not malformed. | 11617 // Type may be malbounded, but not malformed. |
12171 ASSERT(!type.IsMalformed()); | 11618 ASSERT(!type.IsMalformed()); |
12172 selector = new(Z) TypeNode(primary_pos, type); | 11619 selector = new (Z) TypeNode(primary_pos, type); |
12173 } else { | 11620 } else { |
12174 UNREACHABLE(); // Internal parser error. | 11621 UNREACHABLE(); // Internal parser error. |
12175 } | 11622 } |
12176 } else { | 11623 } else { |
12177 // Left is not a primary node; this must be a closure call. | 11624 // Left is not a primary node; this must be a closure call. |
12178 AstNode* closure = left; | 11625 AstNode* closure = left; |
12179 selector = ParseClosureCall(closure); | 11626 selector = ParseClosureCall(closure); |
12180 } | 11627 } |
12181 } else { | 11628 } else { |
12182 // No (more) selectors to parse. | 11629 // No (more) selectors to parse. |
12183 left = LoadFieldIfUnresolved(left); | 11630 left = LoadFieldIfUnresolved(left); |
12184 if (left->IsPrimaryNode()) { | 11631 if (left->IsPrimaryNode()) { |
12185 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11632 PrimaryNode* primary_node = left->AsPrimaryNode(); |
12186 const TokenPosition primary_pos = primary->token_pos(); | 11633 const TokenPosition primary_pos = primary->token_pos(); |
12187 if (primary_node->primary().IsFunction()) { | 11634 if (primary_node->primary().IsFunction()) { |
12188 // Treat as implicit closure. | 11635 // Treat as implicit closure. |
12189 left = LoadClosure(primary_node); | 11636 left = LoadClosure(primary_node); |
12190 } else if (primary_node->primary().IsClass()) { | 11637 } else if (primary_node->primary().IsClass()) { |
12191 const Class& type_class = Class::Cast(primary_node->primary()); | 11638 const Class& type_class = Class::Cast(primary_node->primary()); |
12192 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 11639 AbstractType& type = Type::ZoneHandle( |
12193 type_class, TypeArguments::Handle(Z), primary_pos, Heap::kOld)); | 11640 Z, Type::New(type_class, TypeArguments::Handle(Z), primary_pos, |
12194 type = ClassFinalizer::FinalizeType( | 11641 Heap::kOld)); |
12195 current_class(), type, ClassFinalizer::kCanonicalize); | 11642 type = ClassFinalizer::FinalizeType(current_class(), type, |
| 11643 ClassFinalizer::kCanonicalize); |
12196 // Type may be malbounded, but not malformed. | 11644 // Type may be malbounded, but not malformed. |
12197 ASSERT(!type.IsMalformed()); | 11645 ASSERT(!type.IsMalformed()); |
12198 left = new(Z) TypeNode(primary_pos, type); | 11646 left = new (Z) TypeNode(primary_pos, type); |
12199 } else if (primary_node->primary().IsTypeParameter()) { | 11647 } else if (primary_node->primary().IsTypeParameter()) { |
12200 left = LoadTypeParameter(primary_node); | 11648 left = LoadTypeParameter(primary_node); |
12201 } else if (primary_node->IsSuper()) { | 11649 } else if (primary_node->IsSuper()) { |
12202 // Return "super" to handle unary super operator calls, | 11650 // Return "super" to handle unary super operator calls, |
12203 // or to report illegal use of "super" otherwise. | 11651 // or to report illegal use of "super" otherwise. |
12204 left = primary_node; | 11652 left = primary_node; |
12205 } else { | 11653 } else { |
12206 UNREACHABLE(); // Internal parser error. | 11654 UNREACHABLE(); // Internal parser error. |
12207 } | 11655 } |
12208 } | 11656 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12274 | 11722 |
12275 if (obj.IsFunction()) { | 11723 if (obj.IsFunction()) { |
12276 const Function& func = Function::Cast(obj); | 11724 const Function& func = Function::Cast(obj); |
12277 if (!func.IsSetterFunction() || is_setter_name) { | 11725 if (!func.IsSetterFunction() || is_setter_name) { |
12278 return CreateImplicitClosureNode(func, property_pos, NULL); | 11726 return CreateImplicitClosureNode(func, property_pos, NULL); |
12279 } | 11727 } |
12280 } else if (obj.IsField()) { | 11728 } else if (obj.IsField()) { |
12281 const Field& field = Field::Cast(obj); | 11729 const Field& field = Field::Cast(obj); |
12282 if (is_setter_name && !field.is_final()) { | 11730 if (is_setter_name && !field.is_final()) { |
12283 Instance& setter_closure = Instance::ZoneHandle(field.SetterClosure()); | 11731 Instance& setter_closure = Instance::ZoneHandle(field.SetterClosure()); |
12284 return new(Z) LiteralNode(property_pos, setter_closure); | 11732 return new (Z) LiteralNode(property_pos, setter_closure); |
12285 } | 11733 } |
12286 if (!is_setter_name) { | 11734 if (!is_setter_name) { |
12287 Instance& getter_closure = Instance::ZoneHandle(field.GetterClosure()); | 11735 Instance& getter_closure = Instance::ZoneHandle(field.GetterClosure()); |
12288 return new(Z) LiteralNode(property_pos, getter_closure); | 11736 return new (Z) LiteralNode(property_pos, getter_closure); |
12289 } | 11737 } |
12290 } | 11738 } |
12291 return ThrowNoSuchMethodError(property_pos, | 11739 return ThrowNoSuchMethodError( |
12292 current_class(), | 11740 property_pos, current_class(), extractor_name, |
12293 extractor_name, | 11741 NULL, // No arguments. |
12294 NULL, // No arguments. | 11742 InvocationMirror::kTopLevel, |
12295 InvocationMirror::kTopLevel, | 11743 is_setter_name ? InvocationMirror::kSetter : InvocationMirror::kMethod, |
12296 is_setter_name | 11744 NULL); // No existing function. |
12297 ? InvocationMirror::kSetter | |
12298 : InvocationMirror::kMethod, | |
12299 NULL); // No existing function. | |
12300 } | 11745 } |
12301 | 11746 |
12302 // Handle closurization of static properties of classes, C#n. | 11747 // Handle closurization of static properties of classes, C#n. |
12303 if (primary->IsPrimaryNode() && | 11748 if (primary->IsPrimaryNode() && |
12304 primary->AsPrimaryNode()->primary().IsClass()) { | 11749 primary->AsPrimaryNode()->primary().IsClass()) { |
12305 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary()); | 11750 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary()); |
12306 const Field& field = | 11751 const Field& field = |
12307 Field::Handle(Z, cls.LookupStaticField(extractor_name)); | 11752 Field::Handle(Z, cls.LookupStaticField(extractor_name)); |
12308 if (!field.IsNull()) { | 11753 if (!field.IsNull()) { |
12309 if (is_setter_name) { | 11754 if (is_setter_name) { |
12310 extractor_name = Field::SetterName(extractor_name); | 11755 extractor_name = Field::SetterName(extractor_name); |
12311 if (!field.is_final()) { | 11756 if (!field.is_final()) { |
12312 const Instance& setter_closure = | 11757 const Instance& setter_closure = |
12313 Instance::ZoneHandle(Z, field.SetterClosure()); | 11758 Instance::ZoneHandle(Z, field.SetterClosure()); |
12314 ASSERT(setter_closure.IsClosure()); | 11759 ASSERT(setter_closure.IsClosure()); |
12315 // Note: the created closure is cached after it's created | 11760 // Note: the created closure is cached after it's created |
12316 // once. If eager compilation is desired, the compiler can | 11761 // once. If eager compilation is desired, the compiler can |
12317 // be invoked here. The same applies for getters below. | 11762 // be invoked here. The same applies for getters below. |
12318 return new(Z) LiteralNode(property_pos, setter_closure); | 11763 return new (Z) LiteralNode(property_pos, setter_closure); |
12319 } | 11764 } |
12320 } else { | 11765 } else { |
12321 const Instance& getter_closure = | 11766 const Instance& getter_closure = |
12322 Instance::ZoneHandle(Z, field.GetterClosure()); | 11767 Instance::ZoneHandle(Z, field.GetterClosure()); |
12323 ASSERT(getter_closure.IsClosure()); | 11768 ASSERT(getter_closure.IsClosure()); |
12324 return new(Z) LiteralNode(property_pos, getter_closure); | 11769 return new (Z) LiteralNode(property_pos, getter_closure); |
12325 } | 11770 } |
12326 } else { | 11771 } else { |
12327 Function& func = Function::Handle(Z); | 11772 Function& func = Function::Handle(Z); |
12328 if (is_setter_name) { | 11773 if (is_setter_name) { |
12329 extractor_name = Field::SetterName(extractor_name); | 11774 extractor_name = Field::SetterName(extractor_name); |
12330 func = cls.LookupStaticFunction(extractor_name); | 11775 func = cls.LookupStaticFunction(extractor_name); |
12331 } else { | 11776 } else { |
12332 func = cls.LookupStaticFunction(extractor_name); | 11777 func = cls.LookupStaticFunction(extractor_name); |
12333 if (func.IsNull()) { | 11778 if (func.IsNull()) { |
12334 const String& getter_name = | 11779 const String& getter_name = |
12335 String::Handle(Z, Field::GetterName(extractor_name)); | 11780 String::Handle(Z, Field::GetterName(extractor_name)); |
12336 func = cls.LookupStaticFunction(getter_name); | 11781 func = cls.LookupStaticFunction(getter_name); |
12337 } | 11782 } |
12338 } | 11783 } |
12339 if (!func.IsNull()) { | 11784 if (!func.IsNull()) { |
12340 return CreateImplicitClosureNode(func, property_pos, NULL); | 11785 return CreateImplicitClosureNode(func, property_pos, NULL); |
12341 } | 11786 } |
12342 } | 11787 } |
12343 return ThrowNoSuchMethodError(property_pos, | 11788 return ThrowNoSuchMethodError( |
12344 cls, | 11789 property_pos, cls, extractor_name, |
12345 extractor_name, | 11790 NULL, // No arguments. |
12346 NULL, // No arguments. | 11791 InvocationMirror::kStatic, |
12347 InvocationMirror::kStatic, | 11792 is_setter_name ? InvocationMirror::kSetter : InvocationMirror::kMethod, |
12348 is_setter_name | 11793 NULL); // No existing function. |
12349 ? InvocationMirror::kSetter | |
12350 : InvocationMirror::kMethod, | |
12351 NULL); // No existing function. | |
12352 } | 11794 } |
12353 | 11795 |
12354 // Closurization of instance getter, setter, method or operator. | 11796 // Closurization of instance getter, setter, method or operator. |
12355 GrowableHandlePtrArray<const String> pieces(Z, 3); | 11797 GrowableHandlePtrArray<const String> pieces(Z, 3); |
12356 pieces.Add(Symbols::HashMark()); | 11798 pieces.Add(Symbols::HashMark()); |
12357 if (is_setter_name) { | 11799 if (is_setter_name) { |
12358 pieces.Add(Symbols::SetterPrefix()); | 11800 pieces.Add(Symbols::SetterPrefix()); |
12359 } | 11801 } |
12360 pieces.Add(extractor_name); | 11802 pieces.Add(extractor_name); |
12361 extractor_name = Symbols::FromConcatAll(T, pieces); | 11803 extractor_name = Symbols::FromConcatAll(T, pieces); |
12362 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); | 11804 return new (Z) InstanceGetterNode(property_pos, primary, extractor_name); |
12363 } | 11805 } |
12364 | 11806 |
12365 | 11807 |
12366 AstNode* Parser::ParsePostfixExpr() { | 11808 AstNode* Parser::ParsePostfixExpr() { |
12367 TRACE_PARSER("ParsePostfixExpr"); | 11809 TRACE_PARSER("ParsePostfixExpr"); |
12368 String* expr_ident = | 11810 String* expr_ident = |
12369 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11811 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
12370 const TokenPosition expr_pos = TokenPos(); | 11812 const TokenPosition expr_pos = TokenPos(); |
12371 AstNode* expr = ParsePrimary(); | 11813 AstNode* expr = ParsePrimary(); |
12372 if (CurrentToken() == Token::kHASH) { | 11814 if (CurrentToken() == Token::kHASH) { |
12373 expr = LoadFieldIfUnresolved(expr); | 11815 expr = LoadFieldIfUnresolved(expr); |
12374 expr = ParseClosurization(expr); | 11816 expr = ParseClosurization(expr); |
12375 } else { | 11817 } else { |
12376 expr = ParseSelectors(expr, false); | 11818 expr = ParseSelectors(expr, false); |
12377 } | 11819 } |
12378 if (IsIncrementOperator(CurrentToken())) { | 11820 if (IsIncrementOperator(CurrentToken())) { |
12379 TRACE_PARSER("IncrementOperator"); | 11821 TRACE_PARSER("IncrementOperator"); |
12380 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11822 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
12381 ReportError(expr_pos, "expression is not assignable"); | 11823 ReportError(expr_pos, "expression is not assignable"); |
12382 } | 11824 } |
12383 Token::Kind incr_op = CurrentToken(); | 11825 Token::Kind incr_op = CurrentToken(); |
12384 const TokenPosition op_pos = TokenPos(); | 11826 const TokenPosition op_pos = TokenPos(); |
12385 ConsumeToken(); | 11827 ConsumeToken(); |
12386 // Not prefix. | 11828 // Not prefix. |
12387 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11829 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
12388 LocalVariable* temp = let_expr->AddInitializer(expr); | 11830 LocalVariable* temp = let_expr->AddInitializer(expr); |
12389 Token::Kind binary_op = | 11831 Token::Kind binary_op = |
12390 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 11832 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
12391 BinaryOpNode* add = new(Z) BinaryOpNode( | 11833 BinaryOpNode* add = new (Z) BinaryOpNode( |
12392 op_pos, | 11834 op_pos, binary_op, new (Z) LoadLocalNode(op_pos, temp), |
12393 binary_op, | 11835 new (Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
12394 new(Z) LoadLocalNode(op_pos, temp), | |
12395 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); | |
12396 AstNode* store = | 11836 AstNode* store = |
12397 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); | 11837 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); |
12398 ASSERT(store != NULL); | 11838 ASSERT(store != NULL); |
12399 // The result is a pair of the (side effects of the) store followed by | 11839 // The result is a pair of the (side effects of the) store followed by |
12400 // the (value of the) initial value temp variable load. | 11840 // the (value of the) initial value temp variable load. |
12401 let_expr->AddNode(store); | 11841 let_expr->AddNode(store); |
12402 let_expr->AddNode(new(Z) LoadLocalNode(op_pos, temp)); | 11842 let_expr->AddNode(new (Z) LoadLocalNode(op_pos, temp)); |
12403 return let_expr; | 11843 return let_expr; |
12404 } | 11844 } |
12405 return expr; | 11845 return expr; |
12406 } | 11846 } |
12407 | 11847 |
12408 | 11848 |
12409 // Resolve the given type and its type arguments from the current function and | 11849 // Resolve the given type and its type arguments from the current function and |
12410 // current class according to the given type finalization mode. | 11850 // current class according to the given type finalization mode. |
12411 // Not all involved type classes may get resolved yet, but at least type | 11851 // Not all involved type classes may get resolved yet, but at least type |
12412 // parameters will get resolved, thereby relieving the class | 11852 // parameters will get resolved, thereby relieving the class |
12413 // finalizer from resolving type parameters out of context. | 11853 // finalizer from resolving type parameters out of context. |
12414 void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, | 11854 void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, |
12415 AbstractType* type) { | 11855 AbstractType* type) { |
12416 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); | 11856 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); |
12417 ASSERT(type != NULL); | 11857 ASSERT(type != NULL); |
12418 if (type->IsResolved()) { | 11858 if (type->IsResolved()) { |
12419 return; | 11859 return; |
12420 } | 11860 } |
12421 // Resolve class. | 11861 // Resolve class. |
12422 if (!type->HasResolvedTypeClass()) { | 11862 if (!type->HasResolvedTypeClass()) { |
12423 const UnresolvedClass& unresolved_class = | 11863 const UnresolvedClass& unresolved_class = |
12424 UnresolvedClass::Handle(Z, type->unresolved_class()); | 11864 UnresolvedClass::Handle(Z, type->unresolved_class()); |
12425 const String& unresolved_class_name = | 11865 const String& unresolved_class_name = |
12426 String::Handle(Z, unresolved_class.ident()); | 11866 String::Handle(Z, unresolved_class.ident()); |
12427 Class& resolved_type_class = Class::Handle(Z); | 11867 Class& resolved_type_class = Class::Handle(Z); |
12428 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 11868 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
12429 // First check if the type is a function type parameter. | 11869 // First check if the type is a function type parameter. |
12430 if (!innermost_function().IsNull()) { | 11870 if (!innermost_function().IsNull()) { |
12431 // TODO(regis): Shortcut this lookup if no generic functions in scope. | 11871 // TODO(regis): Shortcut this lookup if no generic functions in scope. |
12432 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, | 11872 TypeParameter& type_parameter = TypeParameter::ZoneHandle( |
12433 innermost_function().LookupTypeParameter(unresolved_class_name, | 11873 Z, innermost_function().LookupTypeParameter(unresolved_class_name, |
12434 NULL)); | 11874 NULL)); |
12435 if (!type_parameter.IsNull()) { | 11875 if (!type_parameter.IsNull()) { |
12436 // TODO(regis): Check for absence of type arguments. | 11876 // TODO(regis): Check for absence of type arguments. |
12437 // For now, resolve the function type parameter to dynamic. | 11877 // For now, resolve the function type parameter to dynamic. |
12438 *type = Type::DynamicType(); | 11878 *type = Type::DynamicType(); |
12439 return; | 11879 return; |
12440 } | 11880 } |
12441 } | 11881 } |
12442 // Then check if the type is a class type parameter. | 11882 // Then check if the type is a class type parameter. |
12443 const TypeParameter& type_parameter = TypeParameter::Handle(Z, | 11883 const TypeParameter& type_parameter = TypeParameter::Handle( |
12444 current_class().LookupTypeParameter(unresolved_class_name)); | 11884 Z, current_class().LookupTypeParameter(unresolved_class_name)); |
12445 if (!type_parameter.IsNull()) { | 11885 if (!type_parameter.IsNull()) { |
12446 // A type parameter is considered to be a malformed type when | 11886 // A type parameter is considered to be a malformed type when |
12447 // referenced by a static member. | 11887 // referenced by a static member. |
12448 if (ParsingStaticMember()) { | 11888 if (ParsingStaticMember()) { |
12449 *type = ClassFinalizer::NewFinalizedMalformedType( | 11889 *type = ClassFinalizer::NewFinalizedMalformedType( |
12450 Error::Handle(Z), // No previous error. | 11890 Error::Handle(Z), // No previous error. |
12451 script_, | 11891 script_, type->token_pos(), |
12452 type->token_pos(), | |
12453 "type parameter '%s' cannot be referenced " | 11892 "type parameter '%s' cannot be referenced " |
12454 "from static member", | 11893 "from static member", |
12455 String::Handle(Z, type_parameter.name()).ToCString()); | 11894 String::Handle(Z, type_parameter.name()).ToCString()); |
12456 return; | 11895 return; |
12457 } | 11896 } |
12458 // A type parameter cannot be parameterized, so make the type | 11897 // A type parameter cannot be parameterized, so make the type |
12459 // malformed if type arguments have previously been parsed. | 11898 // malformed if type arguments have previously been parsed. |
12460 if (type->arguments() != TypeArguments::null()) { | 11899 if (type->arguments() != TypeArguments::null()) { |
12461 *type = ClassFinalizer::NewFinalizedMalformedType( | 11900 *type = ClassFinalizer::NewFinalizedMalformedType( |
12462 Error::Handle(Z), // No previous error. | 11901 Error::Handle(Z), // No previous error. |
12463 script_, | 11902 script_, type_parameter.token_pos(), |
12464 type_parameter.token_pos(), | |
12465 "type parameter '%s' cannot be parameterized", | 11903 "type parameter '%s' cannot be parameterized", |
12466 String::Handle(Z, type_parameter.name()).ToCString()); | 11904 String::Handle(Z, type_parameter.name()).ToCString()); |
12467 return; | 11905 return; |
12468 } | 11906 } |
12469 *type = type_parameter.raw(); | 11907 *type = type_parameter.raw(); |
12470 return; | 11908 return; |
12471 } | 11909 } |
12472 // The referenced class may not have been parsed yet. It would be wrong | 11910 // The referenced class may not have been parsed yet. It would be wrong |
12473 // to resolve it too early to an imported class of the same name. Only | 11911 // to resolve it too early to an imported class of the same name. Only |
12474 // resolve the class when a finalized type is requested. | 11912 // resolve the class when a finalized type is requested. |
12475 if (finalization > ClassFinalizer::kResolveTypeParameters) { | 11913 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
12476 resolved_type_class = library_.LookupClass(unresolved_class_name); | 11914 resolved_type_class = library_.LookupClass(unresolved_class_name); |
12477 } | 11915 } |
12478 } else { | 11916 } else { |
12479 // Resolve class name in the scope of the library prefix. | 11917 // Resolve class name in the scope of the library prefix. |
12480 const LibraryPrefix& lib_prefix = | 11918 const LibraryPrefix& lib_prefix = |
12481 LibraryPrefix::Handle(Z, unresolved_class.library_prefix()); | 11919 LibraryPrefix::Handle(Z, unresolved_class.library_prefix()); |
12482 resolved_type_class = lib_prefix.LookupClass(unresolved_class_name); | 11920 resolved_type_class = lib_prefix.LookupClass(unresolved_class_name); |
12483 } | 11921 } |
12484 // At this point, we can only have a parameterized_type. | 11922 // At this point, we can only have a parameterized_type. |
12485 const Type& parameterized_type = Type::Cast(*type); | 11923 const Type& parameterized_type = Type::Cast(*type); |
12486 if (!resolved_type_class.IsNull()) { | 11924 if (!resolved_type_class.IsNull()) { |
12487 // Replace unresolved class with resolved type class. | 11925 // Replace unresolved class with resolved type class. |
12488 parameterized_type.set_type_class(resolved_type_class); | 11926 parameterized_type.set_type_class(resolved_type_class); |
12489 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 11927 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
12490 ClassFinalizer::FinalizeMalformedType( | 11928 ClassFinalizer::FinalizeMalformedType( |
12491 Error::Handle(Z), // No previous error. | 11929 Error::Handle(Z), // No previous error. |
12492 script_, | 11930 script_, parameterized_type, "type '%s' is not loaded", |
12493 parameterized_type, | |
12494 "type '%s' is not loaded", | |
12495 String::Handle(Z, parameterized_type.UserVisibleName()).ToCString()); | 11931 String::Handle(Z, parameterized_type.UserVisibleName()).ToCString()); |
12496 return; | 11932 return; |
12497 } | 11933 } |
12498 } | 11934 } |
12499 // Resolve type arguments, if any. | 11935 // Resolve type arguments, if any. |
12500 if (type->arguments() != TypeArguments::null()) { | 11936 if (type->arguments() != TypeArguments::null()) { |
12501 const TypeArguments& arguments = | 11937 const TypeArguments& arguments = |
12502 TypeArguments::Handle(Z, type->arguments()); | 11938 TypeArguments::Handle(Z, type->arguments()); |
12503 const intptr_t num_arguments = arguments.Length(); | 11939 const intptr_t num_arguments = arguments.Length(); |
12504 AbstractType& type_argument = AbstractType::Handle(Z); | 11940 AbstractType& type_argument = AbstractType::Handle(Z); |
(...skipping 23 matching lines...) Expand all Loading... |
12528 if (current_function().is_static()) { | 11964 if (current_function().is_static()) { |
12529 ReportError(field_pos, | 11965 ReportError(field_pos, |
12530 "cannot access instance field '%s' from a static function", | 11966 "cannot access instance field '%s' from a static function", |
12531 field_name.ToCString()); | 11967 field_name.ToCString()); |
12532 } | 11968 } |
12533 } | 11969 } |
12534 | 11970 |
12535 | 11971 |
12536 bool Parser::ParsingStaticMember() const { | 11972 bool Parser::ParsingStaticMember() const { |
12537 if (is_top_level_) { | 11973 if (is_top_level_) { |
12538 return (current_member_ != NULL) && | 11974 return (current_member_ != NULL) && current_member_->has_static && |
12539 current_member_->has_static && !current_member_->has_factory; | 11975 !current_member_->has_factory; |
12540 } | 11976 } |
12541 ASSERT(!current_function().IsNull()); | 11977 ASSERT(!current_function().IsNull()); |
12542 return | 11978 return current_function().is_static() && |
12543 current_function().is_static() && !current_function().IsInFactoryScope(); | 11979 !current_function().IsInFactoryScope(); |
12544 } | 11980 } |
12545 | 11981 |
12546 | 11982 |
12547 const AbstractType* Parser::ReceiverType(const Class& cls) { | 11983 const AbstractType* Parser::ReceiverType(const Class& cls) { |
12548 ASSERT(!cls.IsNull()); | 11984 ASSERT(!cls.IsNull()); |
12549 ASSERT(!cls.IsTypedefClass()); | 11985 ASSERT(!cls.IsTypedefClass()); |
12550 // Note that if cls is _Closure, the returned type will be _Closure, | 11986 // Note that if cls is _Closure, the returned type will be _Closure, |
12551 // and not the signature type. | 11987 // and not the signature type. |
12552 Type& type = Type::ZoneHandle(Z, cls.CanonicalType()); | 11988 Type& type = Type::ZoneHandle(Z, cls.CanonicalType()); |
12553 if (!type.IsNull()) { | 11989 if (!type.IsNull()) { |
(...skipping 21 matching lines...) Expand all Loading... |
12575 } | 12011 } |
12576 | 12012 |
12577 | 12013 |
12578 void Parser::InsertCachedConstantValue(const Script& script, | 12014 void Parser::InsertCachedConstantValue(const Script& script, |
12579 TokenPosition token_pos, | 12015 TokenPosition token_pos, |
12580 const Instance& value) { | 12016 const Instance& value) { |
12581 ASSERT(Thread::Current()->IsMutatorThread()); | 12017 ASSERT(Thread::Current()->IsMutatorThread()); |
12582 const intptr_t kInitialConstMapSize = 16; | 12018 const intptr_t kInitialConstMapSize = 16; |
12583 ASSERT(!script.InVMHeap()); | 12019 ASSERT(!script.InVMHeap()); |
12584 if (script.compile_time_constants() == Array::null()) { | 12020 if (script.compile_time_constants() == Array::null()) { |
12585 const Array& array = | 12021 const Array& array = Array::Handle( |
12586 Array::Handle(HashTables::New<ConstantsMap>(kInitialConstMapSize, | 12022 HashTables::New<ConstantsMap>(kInitialConstMapSize, Heap::kNew)); |
12587 Heap::kNew)); | |
12588 script.set_compile_time_constants(array); | 12023 script.set_compile_time_constants(array); |
12589 } | 12024 } |
12590 ConstantsMap constants(script.compile_time_constants()); | 12025 ConstantsMap constants(script.compile_time_constants()); |
12591 constants.InsertNewOrGetValue(token_pos, value); | 12026 constants.InsertNewOrGetValue(token_pos, value); |
12592 script.set_compile_time_constants(constants.Release()); | 12027 script.set_compile_time_constants(constants.Release()); |
12593 } | 12028 } |
12594 | 12029 |
12595 | 12030 |
12596 void Parser::CacheConstantValue(TokenPosition token_pos, | 12031 void Parser::CacheConstantValue(TokenPosition token_pos, |
12597 const Instance& value) { | 12032 const Instance& value) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12636 ReportError(token_pos, "Invalid const object %s", error_str); | 12071 ReportError(token_pos, "Invalid const object %s", error_str); |
12637 } | 12072 } |
12638 return result.raw(); | 12073 return result.raw(); |
12639 } | 12074 } |
12640 | 12075 |
12641 | 12076 |
12642 // If the field is already initialized, return no ast (NULL). | 12077 // If the field is already initialized, return no ast (NULL). |
12643 // Otherwise, if the field is constant, initialize the field and return no ast. | 12078 // Otherwise, if the field is constant, initialize the field and return no ast. |
12644 // If the field is not initialized and not const, return the ast for the getter. | 12079 // If the field is not initialized and not const, return the ast for the getter. |
12645 StaticGetterNode* Parser::RunStaticFieldInitializer( | 12080 StaticGetterNode* Parser::RunStaticFieldInitializer( |
12646 const Field& field, TokenPosition field_ref_pos) { | 12081 const Field& field, |
| 12082 TokenPosition field_ref_pos) { |
12647 ASSERT(field.is_static()); | 12083 ASSERT(field.is_static()); |
12648 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); | 12084 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); |
12649 const String& field_name = String::ZoneHandle(Z, field.name()); | 12085 const String& field_name = String::ZoneHandle(Z, field.name()); |
12650 const String& getter_name = | 12086 const String& getter_name = |
12651 String::Handle(Z, Field::GetterSymbol(field_name)); | 12087 String::Handle(Z, Field::GetterSymbol(field_name)); |
12652 const Function& getter = Function::Handle(Z, | 12088 const Function& getter = |
12653 field_owner.LookupStaticFunction(getter_name)); | 12089 Function::Handle(Z, field_owner.LookupStaticFunction(getter_name)); |
12654 const Instance& value = Instance::Handle(Z, field.StaticValue()); | 12090 const Instance& value = Instance::Handle(Z, field.StaticValue()); |
12655 if (value.raw() == Object::transition_sentinel().raw()) { | 12091 if (value.raw() == Object::transition_sentinel().raw()) { |
12656 if (field.is_const()) { | 12092 if (field.is_const()) { |
12657 ReportError("circular dependency while initializing static field '%s'", | 12093 ReportError("circular dependency while initializing static field '%s'", |
12658 field_name.ToCString()); | 12094 field_name.ToCString()); |
12659 } else { | 12095 } else { |
12660 // The implicit static getter will throw the exception if necessary. | 12096 // The implicit static getter will throw the exception if necessary. |
12661 return new(Z) StaticGetterNode( | 12097 return new (Z) |
12662 field_ref_pos, NULL, field_owner, field_name); | 12098 StaticGetterNode(field_ref_pos, NULL, field_owner, field_name); |
12663 } | 12099 } |
12664 } else if (value.raw() == Object::sentinel().raw()) { | 12100 } else if (value.raw() == Object::sentinel().raw()) { |
12665 // This field has not been referenced yet and thus the value has | 12101 // This field has not been referenced yet and thus the value has |
12666 // not been evaluated. If the field is const, call the static getter method | 12102 // not been evaluated. If the field is const, call the static getter method |
12667 // to evaluate the expression and canonicalize the value. | 12103 // to evaluate the expression and canonicalize the value. |
12668 if (field.is_const()) { | 12104 if (field.is_const()) { |
12669 NoReloadScope no_reload_scope(isolate(), thread()); | 12105 NoReloadScope no_reload_scope(isolate(), thread()); |
12670 NoOOBMessageScope no_msg_scope(thread()); | 12106 NoOOBMessageScope no_msg_scope(thread()); |
12671 field.SetStaticValue(Object::transition_sentinel()); | 12107 field.SetStaticValue(Object::transition_sentinel()); |
12672 const int kNumArguments = 0; // no arguments. | 12108 const int kNumArguments = 0; // no arguments. |
12673 const Function& func = Function::Handle(Z, | 12109 const Function& func = Function::Handle( |
12674 Resolver::ResolveStatic(field_owner, | 12110 Z, Resolver::ResolveStatic(field_owner, getter_name, kNumArguments, |
12675 getter_name, | 12111 Object::empty_array())); |
12676 kNumArguments, | |
12677 Object::empty_array())); | |
12678 ASSERT(!func.IsNull()); | 12112 ASSERT(!func.IsNull()); |
12679 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); | 12113 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
12680 Object& const_value = Object::Handle(Z); | 12114 Object& const_value = Object::Handle(Z); |
12681 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); | 12115 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); |
12682 if (const_value.IsError()) { | 12116 if (const_value.IsError()) { |
12683 const Error& error = Error::Cast(const_value); | 12117 const Error& error = Error::Cast(const_value); |
12684 if (error.IsUnhandledException()) { | 12118 if (error.IsUnhandledException()) { |
12685 // An exception may not occur in every parse attempt, i.e., the | 12119 // An exception may not occur in every parse attempt, i.e., the |
12686 // generated AST is not deterministic. Therefore mark the function as | 12120 // generated AST is not deterministic. Therefore mark the function as |
12687 // not optimizable. | 12121 // not optimizable. |
12688 current_function().SetIsOptimizable(false); | 12122 current_function().SetIsOptimizable(false); |
12689 field.SetStaticValue(Object::null_instance()); | 12123 field.SetStaticValue(Object::null_instance()); |
12690 // It is a compile-time error if evaluation of a compile-time constant | 12124 // It is a compile-time error if evaluation of a compile-time constant |
12691 // would raise an exception. | 12125 // would raise an exception. |
12692 const String& field_name = String::Handle(Z, field.name()); | 12126 const String& field_name = String::Handle(Z, field.name()); |
12693 ReportErrors(error, | 12127 ReportErrors(error, script_, field_ref_pos, |
12694 script_, field_ref_pos, | |
12695 "error initializing const field '%s'", | 12128 "error initializing const field '%s'", |
12696 field_name.ToCString()); | 12129 field_name.ToCString()); |
12697 } else { | 12130 } else { |
12698 ReportError(error); | 12131 ReportError(error); |
12699 } | 12132 } |
12700 UNREACHABLE(); | 12133 UNREACHABLE(); |
12701 } | 12134 } |
12702 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 12135 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
12703 Instance& instance = Instance::Handle(Z); | 12136 Instance& instance = Instance::Handle(Z); |
12704 instance ^= const_value.raw(); | 12137 instance ^= const_value.raw(); |
12705 instance = TryCanonicalize(instance, field_ref_pos); | 12138 instance = TryCanonicalize(instance, field_ref_pos); |
12706 field.SetStaticValue(instance); | 12139 field.SetStaticValue(instance); |
12707 return NULL; // Constant | 12140 return NULL; // Constant |
12708 } else { | 12141 } else { |
12709 return new(Z) StaticGetterNode( | 12142 return new (Z) |
12710 field_ref_pos, NULL, field_owner, field_name); | 12143 StaticGetterNode(field_ref_pos, NULL, field_owner, field_name); |
12711 } | 12144 } |
12712 } | 12145 } |
12713 if (getter.IsNull() || | 12146 if (getter.IsNull() || |
12714 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { | 12147 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
12715 return NULL; | 12148 return NULL; |
12716 } | 12149 } |
12717 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 12150 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
12718 return new(Z) StaticGetterNode( | 12151 return new (Z) StaticGetterNode(field_ref_pos, NULL, field_owner, field_name); |
12719 field_ref_pos, NULL, field_owner, field_name); | |
12720 } | 12152 } |
12721 | 12153 |
12722 | 12154 |
12723 RawObject* Parser::EvaluateConstConstructorCall( | 12155 RawObject* Parser::EvaluateConstConstructorCall( |
12724 const Class& type_class, | 12156 const Class& type_class, |
12725 const TypeArguments& type_arguments, | 12157 const TypeArguments& type_arguments, |
12726 const Function& constructor, | 12158 const Function& constructor, |
12727 ArgumentListNode* arguments) { | 12159 ArgumentListNode* arguments) { |
12728 NoReloadScope no_reload_scope(isolate(), thread()); | 12160 NoReloadScope no_reload_scope(isolate(), thread()); |
12729 NoOOBMessageScope no_msg_scope(thread()); | 12161 NoOOBMessageScope no_msg_scope(thread()); |
(...skipping 18 matching lines...) Expand all Loading... |
12748 // Prepend type_arguments to list of arguments to factory. | 12180 // Prepend type_arguments to list of arguments to factory. |
12749 ASSERT(type_arguments.IsZoneHandle()); | 12181 ASSERT(type_arguments.IsZoneHandle()); |
12750 arg_values.SetAt(0, type_arguments); | 12182 arg_values.SetAt(0, type_arguments); |
12751 } | 12183 } |
12752 for (int i = 0; i < arguments->length(); i++) { | 12184 for (int i = 0; i < arguments->length(); i++) { |
12753 AstNode* arg = arguments->NodeAt(i); | 12185 AstNode* arg = arguments->NodeAt(i); |
12754 // Arguments have been evaluated to a literal value already. | 12186 // Arguments have been evaluated to a literal value already. |
12755 ASSERT(arg->IsLiteralNode()); | 12187 ASSERT(arg->IsLiteralNode()); |
12756 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 12188 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
12757 } | 12189 } |
12758 const Array& args_descriptor = Array::Handle(Z, | 12190 const Array& args_descriptor = Array::Handle( |
12759 ArgumentsDescriptor::New(num_arguments, arguments->names())); | 12191 Z, ArgumentsDescriptor::New(num_arguments, arguments->names())); |
12760 const Object& result = Object::Handle(Z, | 12192 const Object& result = Object::Handle( |
12761 DartEntry::InvokeFunction(constructor, arg_values, args_descriptor)); | 12193 Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor)); |
12762 if (result.IsError()) { | 12194 if (result.IsError()) { |
12763 // An exception may not occur in every parse attempt, i.e., the | 12195 // An exception may not occur in every parse attempt, i.e., the |
12764 // generated AST is not deterministic. Therefore mark the function as | 12196 // generated AST is not deterministic. Therefore mark the function as |
12765 // not optimizable. | 12197 // not optimizable. |
12766 current_function().SetIsOptimizable(false); | 12198 current_function().SetIsOptimizable(false); |
12767 if (result.IsUnhandledException()) { | 12199 if (result.IsUnhandledException()) { |
12768 return result.raw(); | 12200 return result.raw(); |
12769 } else { | 12201 } else { |
12770 thread()->long_jump_base()->Jump(1, Error::Cast(result)); | 12202 thread()->long_jump_base()->Jump(1, Error::Cast(result)); |
12771 UNREACHABLE(); | 12203 UNREACHABLE(); |
12772 return Object::null(); | 12204 return Object::null(); |
12773 } | 12205 } |
12774 } else { | 12206 } else { |
12775 if (constructor.IsFactory()) { | 12207 if (constructor.IsFactory()) { |
12776 // The factory method returns the allocated object. | 12208 // The factory method returns the allocated object. |
12777 instance ^= result.raw(); | 12209 instance ^= result.raw(); |
12778 } | 12210 } |
12779 return TryCanonicalize(instance, TokenPos()); | 12211 return TryCanonicalize(instance, TokenPos()); |
12780 } | 12212 } |
12781 } | 12213 } |
12782 | 12214 |
12783 | 12215 |
12784 // Do a lookup for the identifier in the block scope and the class scope | 12216 // Do a lookup for the identifier in the block scope and the class scope |
12785 // return true if the identifier is found, false otherwise. | 12217 // return true if the identifier is found, false otherwise. |
12786 // If node is non NULL return an AST node corresponding to the identifier. | 12218 // If node is non NULL return an AST node corresponding to the identifier. |
12787 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, | 12219 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, |
12788 const String &ident, | 12220 const String& ident, |
12789 AstNode** node, | 12221 AstNode** node, |
12790 intptr_t* function_level) { | 12222 intptr_t* function_level) { |
12791 TRACE_PARSER("ResolveIdentInLocalScope"); | 12223 TRACE_PARSER("ResolveIdentInLocalScope"); |
12792 // First try to find the identifier in the nested local scopes. | 12224 // First try to find the identifier in the nested local scopes. |
12793 LocalVariable* local = LookupLocalScope(ident); | 12225 LocalVariable* local = LookupLocalScope(ident); |
12794 if (current_block_ != NULL) { | 12226 if (current_block_ != NULL) { |
12795 current_block_->scope->AddReferencedName(ident_pos, ident); | 12227 current_block_->scope->AddReferencedName(ident_pos, ident); |
12796 } | 12228 } |
12797 if (local != NULL) { | 12229 if (local != NULL) { |
12798 if (node != NULL) { | 12230 if (node != NULL) { |
12799 *node = new(Z) LoadLocalNode(ident_pos, local); | 12231 *node = new (Z) LoadLocalNode(ident_pos, local); |
12800 } | 12232 } |
12801 if (function_level != NULL) { | 12233 if (function_level != NULL) { |
12802 *function_level = local->owner()->function_level(); | 12234 *function_level = local->owner()->function_level(); |
12803 } | 12235 } |
12804 return true; | 12236 return true; |
12805 } | 12237 } |
12806 | 12238 |
12807 // If we are compiling top-level code, we don't need to look for | 12239 // If we are compiling top-level code, we don't need to look for |
12808 // the identifier in the current (top-level) class. The class scope | 12240 // the identifier in the current (top-level) class. The class scope |
12809 // of the top-level class is part of the library scope. | 12241 // of the top-level class is part of the library scope. |
(...skipping 28 matching lines...) Expand all Loading... |
12838 } | 12270 } |
12839 } | 12271 } |
12840 if (function_level != NULL) { | 12272 if (function_level != NULL) { |
12841 *function_level = 0; | 12273 *function_level = 0; |
12842 } | 12274 } |
12843 return true; | 12275 return true; |
12844 } | 12276 } |
12845 | 12277 |
12846 // Check if an instance/static function exists. | 12278 // Check if an instance/static function exists. |
12847 func = cls.LookupFunction(ident); | 12279 func = cls.LookupFunction(ident); |
12848 if (!func.IsNull() && | 12280 if (!func.IsNull() && (func.IsDynamicFunction() || func.IsStaticFunction() || |
12849 (func.IsDynamicFunction() || | 12281 func.is_abstract())) { |
12850 func.IsStaticFunction() || | |
12851 func.is_abstract())) { | |
12852 if (node != NULL) { | 12282 if (node != NULL) { |
12853 *node = new(Z) PrimaryNode( | 12283 *node = |
12854 ident_pos, Function::ZoneHandle(Z, func.raw())); | 12284 new (Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw())); |
12855 } | 12285 } |
12856 return true; | 12286 return true; |
12857 } | 12287 } |
12858 | 12288 |
12859 // Now check if a getter/setter method exists for it in which case | 12289 // Now check if a getter/setter method exists for it in which case |
12860 // it is still a field. | 12290 // it is still a field. |
12861 // A setter without a corresponding getter binds to the non-existing | 12291 // A setter without a corresponding getter binds to the non-existing |
12862 // getter. (The getter could be followed by an assignment which will | 12292 // getter. (The getter could be followed by an assignment which will |
12863 // convert it to a setter node. If there is no assignment the non-existing | 12293 // convert it to a setter node. If there is no assignment the non-existing |
12864 // getter will throw a NoSuchMethodError.) | 12294 // getter will throw a NoSuchMethodError.) |
12865 func = cls.LookupGetterFunction(ident); | 12295 func = cls.LookupGetterFunction(ident); |
12866 if (func.IsNull()) { | 12296 if (func.IsNull()) { |
12867 func = cls.LookupSetterFunction(ident); | 12297 func = cls.LookupSetterFunction(ident); |
12868 } | 12298 } |
12869 if (!func.IsNull()) { | 12299 if (!func.IsNull()) { |
12870 if (func.IsDynamicFunction() || func.is_abstract()) { | 12300 if (func.IsDynamicFunction() || func.is_abstract()) { |
12871 if (node != NULL) { | 12301 if (node != NULL) { |
12872 CheckInstanceFieldAccess(ident_pos, ident); | 12302 CheckInstanceFieldAccess(ident_pos, ident); |
12873 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 12303 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
12874 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 12304 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
12875 } | 12305 } |
12876 return true; | 12306 return true; |
12877 } else if (func.IsStaticFunction()) { | 12307 } else if (func.IsStaticFunction()) { |
12878 if (node != NULL) { | 12308 if (node != NULL) { |
12879 *node = new(Z) StaticGetterNode(ident_pos, | 12309 *node = new (Z) StaticGetterNode( |
12880 NULL, | 12310 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), ident); |
12881 Class::ZoneHandle(Z, cls.raw()), | |
12882 ident); | |
12883 } | 12311 } |
12884 return true; | 12312 return true; |
12885 } | 12313 } |
12886 } | 12314 } |
12887 | 12315 |
12888 // Nothing found in scope of current class. | 12316 // Nothing found in scope of current class. |
12889 if (node != NULL) { | 12317 if (node != NULL) { |
12890 *node = NULL; | 12318 *node = NULL; |
12891 } | 12319 } |
12892 return false; | 12320 return false; |
12893 } | 12321 } |
12894 | 12322 |
12895 | 12323 |
12896 // Resolve an identifier by checking the global scope of the current | 12324 // Resolve an identifier by checking the global scope of the current |
12897 // library. If not found in the current library, then look in the scopes | 12325 // library. If not found in the current library, then look in the scopes |
12898 // of all libraries that are imported without a library prefix. | 12326 // of all libraries that are imported without a library prefix. |
12899 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos, | 12327 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos, |
12900 const String& ident) { | 12328 const String& ident) { |
12901 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 12329 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
12902 HANDLESCOPE(thread()); | 12330 HANDLESCOPE(thread()); |
12903 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); | 12331 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); |
12904 if (obj.IsClass()) { | 12332 if (obj.IsClass()) { |
12905 const Class& cls = Class::Cast(obj); | 12333 const Class& cls = Class::Cast(obj); |
12906 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); | 12334 return new (Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
12907 } else if (obj.IsField()) { | 12335 } else if (obj.IsField()) { |
12908 const Field& field = Field::Cast(obj); | 12336 const Field& field = Field::Cast(obj); |
12909 ASSERT(field.is_static()); | 12337 ASSERT(field.is_static()); |
12910 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); | 12338 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); |
12911 if (get_field->IsStaticGetterNode()) { | 12339 if (get_field->IsStaticGetterNode()) { |
12912 get_field->AsStaticGetterNode()->set_owner(library_); | 12340 get_field->AsStaticGetterNode()->set_owner(library_); |
12913 } | 12341 } |
12914 return get_field; | 12342 return get_field; |
12915 } else if (obj.IsFunction()) { | 12343 } else if (obj.IsFunction()) { |
12916 const Function& func = Function::Cast(obj); | 12344 const Function& func = Function::Cast(obj); |
12917 ASSERT(func.is_static()); | 12345 ASSERT(func.is_static()); |
12918 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 12346 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
12919 StaticGetterNode* getter = | 12347 StaticGetterNode* getter = new (Z) StaticGetterNode( |
12920 new(Z) StaticGetterNode(ident_pos, | 12348 ident_pos, |
12921 /* receiver */ NULL, | 12349 /* receiver */ NULL, Class::ZoneHandle(Z, func.Owner()), ident); |
12922 Class::ZoneHandle(Z, func.Owner()), | |
12923 ident); | |
12924 getter->set_owner(library_); | 12350 getter->set_owner(library_); |
12925 return getter; | 12351 return getter; |
12926 } else { | 12352 } else { |
12927 return new(Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw())); | 12353 return new (Z) |
| 12354 PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw())); |
12928 } | 12355 } |
12929 } else if (obj.IsLibraryPrefix()) { | 12356 } else if (obj.IsLibraryPrefix()) { |
12930 const LibraryPrefix& prefix = LibraryPrefix::Cast(obj); | 12357 const LibraryPrefix& prefix = LibraryPrefix::Cast(obj); |
12931 ReportError(ident_pos, | 12358 ReportError(ident_pos, "illegal use of library prefix '%s'", |
12932 "illegal use of library prefix '%s'", | |
12933 String::Handle(prefix.name()).ToCString()); | 12359 String::Handle(prefix.name()).ToCString()); |
12934 } else { | 12360 } else { |
12935 ASSERT(obj.IsNull()); | 12361 ASSERT(obj.IsNull()); |
12936 } | 12362 } |
12937 // Lexically unresolved primary identifiers are referenced by their name. | 12363 // Lexically unresolved primary identifiers are referenced by their name. |
12938 return new(Z) PrimaryNode(ident_pos, ident); | 12364 return new (Z) PrimaryNode(ident_pos, ident); |
12939 } | 12365 } |
12940 | 12366 |
12941 | 12367 |
12942 // Do a lookup for the identifier in the scope of the specified | 12368 // Do a lookup for the identifier in the scope of the specified |
12943 // library prefix. This means trying to resolve it locally in all of the | 12369 // library prefix. This means trying to resolve it locally in all of the |
12944 // libraries present in the library prefix. | 12370 // libraries present in the library prefix. |
12945 AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos, | 12371 AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos, |
12946 const LibraryPrefix& prefix, | 12372 const LibraryPrefix& prefix, |
12947 const String& ident) { | 12373 const String& ident) { |
12948 TRACE_PARSER("ResolveIdentInPrefixScope"); | 12374 TRACE_PARSER("ResolveIdentInPrefixScope"); |
(...skipping 18 matching lines...) Expand all Loading... |
12967 parsed_function()->AddDeferredPrefix(prefix); | 12393 parsed_function()->AddDeferredPrefix(prefix); |
12968 } | 12394 } |
12969 } | 12395 } |
12970 const bool is_deferred = prefix.is_deferred_load(); | 12396 const bool is_deferred = prefix.is_deferred_load(); |
12971 if (obj.IsNull()) { | 12397 if (obj.IsNull()) { |
12972 // Unresolved prefixed primary identifier. | 12398 // Unresolved prefixed primary identifier. |
12973 return NULL; | 12399 return NULL; |
12974 } else if (obj.IsClass()) { | 12400 } else if (obj.IsClass()) { |
12975 const Class& cls = Class::Cast(obj); | 12401 const Class& cls = Class::Cast(obj); |
12976 PrimaryNode* primary = | 12402 PrimaryNode* primary = |
12977 new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); | 12403 new (Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
12978 primary->set_is_deferred(is_deferred); | 12404 primary->set_is_deferred(is_deferred); |
12979 return primary; | 12405 return primary; |
12980 } else if (obj.IsField()) { | 12406 } else if (obj.IsField()) { |
12981 const Field& field = Field::Cast(obj); | 12407 const Field& field = Field::Cast(obj); |
12982 ASSERT(field.is_static()); | 12408 ASSERT(field.is_static()); |
12983 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); | 12409 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); |
12984 ASSERT(get_field != NULL); | 12410 ASSERT(get_field != NULL); |
12985 ASSERT(get_field->IsLoadStaticFieldNode() || | 12411 ASSERT(get_field->IsLoadStaticFieldNode() || |
12986 get_field->IsStaticGetterNode()); | 12412 get_field->IsStaticGetterNode()); |
12987 if (get_field->IsLoadStaticFieldNode()) { | 12413 if (get_field->IsLoadStaticFieldNode()) { |
12988 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 12414 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
12989 } else if (get_field->IsStaticGetterNode()) { | 12415 } else if (get_field->IsStaticGetterNode()) { |
12990 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); | 12416 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); |
12991 get_field->AsStaticGetterNode()->set_owner(prefix); | 12417 get_field->AsStaticGetterNode()->set_owner(prefix); |
12992 } | 12418 } |
12993 return get_field; | 12419 return get_field; |
12994 } else if (obj.IsFunction()) { | 12420 } else if (obj.IsFunction()) { |
12995 const Function& func = Function::Cast(obj); | 12421 const Function& func = Function::Cast(obj); |
12996 ASSERT(func.is_static()); | 12422 ASSERT(func.is_static()); |
12997 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 12423 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
12998 StaticGetterNode* getter = new(Z) StaticGetterNode( | 12424 StaticGetterNode* getter = new (Z) StaticGetterNode( |
12999 ident_pos, | 12425 ident_pos, |
13000 /* receiver */ NULL, | 12426 /* receiver */ NULL, Class::ZoneHandle(Z, func.Owner()), ident); |
13001 Class::ZoneHandle(Z, func.Owner()), | |
13002 ident); | |
13003 getter->set_is_deferred(is_deferred); | 12427 getter->set_is_deferred(is_deferred); |
13004 getter->set_owner(prefix); | 12428 getter->set_owner(prefix); |
13005 return getter; | 12429 return getter; |
13006 } else { | 12430 } else { |
13007 PrimaryNode* primary = new(Z) PrimaryNode( | 12431 PrimaryNode* primary = |
13008 ident_pos, Function::ZoneHandle(Z, func.raw())); | 12432 new (Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw())); |
13009 primary->set_is_deferred(is_deferred); | 12433 primary->set_is_deferred(is_deferred); |
13010 return primary; | 12434 return primary; |
13011 } | 12435 } |
13012 } | 12436 } |
13013 // All possible object types are handled above. | 12437 // All possible object types are handled above. |
13014 UNREACHABLE(); | 12438 UNREACHABLE(); |
13015 return NULL; | 12439 return NULL; |
13016 } | 12440 } |
13017 | 12441 |
13018 | 12442 |
13019 // Resolve identifier. Issue an error message if | 12443 // Resolve identifier. Issue an error message if |
13020 // the ident refers to a method and allow_closure_names is false. | 12444 // the ident refers to a method and allow_closure_names is false. |
13021 // If the name cannot be resolved, turn it into an instance field access | 12445 // If the name cannot be resolved, turn it into an instance field access |
13022 // if we're compiling an instance method, or generate | 12446 // if we're compiling an instance method, or generate |
13023 // throw NoSuchMethodError if we're compiling a static method. | 12447 // throw NoSuchMethodError if we're compiling a static method. |
13024 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, | 12448 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, |
13025 const String& ident, | 12449 const String& ident, |
13026 bool allow_closure_names) { | 12450 bool allow_closure_names) { |
13027 TRACE_PARSER("ResolveIdent"); | 12451 TRACE_PARSER("ResolveIdent"); |
13028 // First try to find the variable in the local scope (block scope or | 12452 // First try to find the variable in the local scope (block scope or |
13029 // class scope). | 12453 // class scope). |
13030 AstNode* resolved = NULL; | 12454 AstNode* resolved = NULL; |
13031 intptr_t resolved_func_level = 0; | 12455 intptr_t resolved_func_level = 0; |
13032 ResolveIdentInLocalScope(ident_pos, ident, &resolved, &resolved_func_level); | 12456 ResolveIdentInLocalScope(ident_pos, ident, &resolved, &resolved_func_level); |
13033 if (!innermost_function().IsNull()) { | 12457 if (!innermost_function().IsNull()) { |
13034 // TODO(regis): Shortcut this lookup if no generic functions in scope. | 12458 // TODO(regis): Shortcut this lookup if no generic functions in scope. |
13035 intptr_t type_param_func_level = FunctionLevel(); | 12459 intptr_t type_param_func_level = FunctionLevel(); |
13036 const TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, | 12460 const TypeParameter& type_parameter = |
13037 innermost_function().LookupTypeParameter(ident, | 12461 TypeParameter::ZoneHandle(Z, innermost_function().LookupTypeParameter( |
13038 &type_param_func_level)); | 12462 ident, &type_param_func_level)); |
13039 if (!type_parameter.IsNull()) { | 12463 if (!type_parameter.IsNull()) { |
13040 if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) { | 12464 if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) { |
13041 // The identifier is a function type parameter, possibly shadowing | 12465 // The identifier is a function type parameter, possibly shadowing |
13042 // 'resolved'. | 12466 // 'resolved'. |
13043 if (type_param_func_level < FunctionLevel()) { | 12467 if (type_param_func_level < FunctionLevel()) { |
13044 // Make sure that the function instantiator is captured. | 12468 // Make sure that the function instantiator is captured. |
13045 CaptureFunctionInstantiator(); | 12469 CaptureFunctionInstantiator(); |
13046 } | 12470 } |
13047 // TODO(regis): Finalize type parameter and return as type node. | 12471 // TODO(regis): Finalize type parameter and return as type node. |
13048 // For now, map to dynamic type. | 12472 // For now, map to dynamic type. |
13049 Type& type = Type::ZoneHandle(Z, Type::DynamicType()); | 12473 Type& type = Type::ZoneHandle(Z, Type::DynamicType()); |
13050 return new(Z) TypeNode(ident_pos, type); | 12474 return new (Z) TypeNode(ident_pos, type); |
13051 } | 12475 } |
13052 } | 12476 } |
13053 } | 12477 } |
13054 if (resolved == NULL) { | 12478 if (resolved == NULL) { |
13055 // Check whether the identifier is a class type parameter. | 12479 // Check whether the identifier is a class type parameter. |
13056 if (!current_class().IsNull()) { | 12480 if (!current_class().IsNull()) { |
13057 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, | 12481 TypeParameter& type_parameter = TypeParameter::ZoneHandle( |
13058 current_class().LookupTypeParameter(ident)); | 12482 Z, current_class().LookupTypeParameter(ident)); |
13059 if (!type_parameter.IsNull()) { | 12483 if (!type_parameter.IsNull()) { |
13060 if (FunctionLevel() > 0) { | 12484 if (FunctionLevel() > 0) { |
13061 // Make sure that the class instantiator is captured. | 12485 // Make sure that the class instantiator is captured. |
13062 CaptureInstantiator(); | 12486 CaptureInstantiator(); |
13063 } | 12487 } |
13064 type_parameter ^= ClassFinalizer::FinalizeType( | 12488 type_parameter ^= ClassFinalizer::FinalizeType( |
13065 current_class(), type_parameter, ClassFinalizer::kCanonicalize); | 12489 current_class(), type_parameter, ClassFinalizer::kCanonicalize); |
13066 ASSERT(!type_parameter.IsMalformed()); | 12490 ASSERT(!type_parameter.IsMalformed()); |
13067 return new(Z) TypeNode(ident_pos, type_parameter); | 12491 return new (Z) TypeNode(ident_pos, type_parameter); |
13068 } | 12492 } |
13069 } | 12493 } |
13070 // Not found in the local scope, and the name is not a type parameter. | 12494 // Not found in the local scope, and the name is not a type parameter. |
13071 // Try finding the variable in the library scope (current library | 12495 // Try finding the variable in the library scope (current library |
13072 // and all libraries imported by it without a library prefix). | 12496 // and all libraries imported by it without a library prefix). |
13073 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 12497 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
13074 } | 12498 } |
13075 if (resolved->IsPrimaryNode()) { | 12499 if (resolved->IsPrimaryNode()) { |
13076 PrimaryNode* primary = resolved->AsPrimaryNode(); | 12500 PrimaryNode* primary = resolved->AsPrimaryNode(); |
13077 const TokenPosition primary_pos = primary->token_pos(); | 12501 const TokenPosition primary_pos = primary->token_pos(); |
13078 if (primary->primary().IsString()) { | 12502 if (primary->primary().IsString()) { |
13079 // We got an unresolved name. If we are compiling a static | 12503 // We got an unresolved name. If we are compiling a static |
13080 // method, evaluation of an unresolved identifier causes a | 12504 // method, evaluation of an unresolved identifier causes a |
13081 // NoSuchMethodError to be thrown. In an instance method, we convert | 12505 // NoSuchMethodError to be thrown. In an instance method, we convert |
13082 // the unresolved name to an instance field access, since a | 12506 // the unresolved name to an instance field access, since a |
13083 // subclass might define a field with this name. | 12507 // subclass might define a field with this name. |
13084 if (current_function().is_static()) { | 12508 if (current_function().is_static()) { |
13085 resolved = ThrowNoSuchMethodError(ident_pos, | 12509 resolved = ThrowNoSuchMethodError(ident_pos, current_class(), ident, |
13086 current_class(), | |
13087 ident, | |
13088 NULL, // No arguments. | 12510 NULL, // No arguments. |
13089 InvocationMirror::kStatic, | 12511 InvocationMirror::kStatic, |
13090 InvocationMirror::kField, | 12512 InvocationMirror::kField, |
13091 NULL); // No existing function. | 12513 NULL); // No existing function. |
13092 } else { | 12514 } else { |
13093 // Treat as call to unresolved instance field. | 12515 // Treat as call to unresolved instance field. |
13094 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 12516 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
13095 } | 12517 } |
13096 } else if (primary->primary().IsFunction()) { | 12518 } else if (primary->primary().IsFunction()) { |
13097 if (allow_closure_names) { | 12519 if (allow_closure_names) { |
13098 resolved = LoadClosure(primary); | 12520 resolved = LoadClosure(primary); |
13099 } else { | 12521 } else { |
13100 ReportError(ident_pos, "illegal reference to method '%s'", | 12522 ReportError(ident_pos, "illegal reference to method '%s'", |
13101 ident.ToCString()); | 12523 ident.ToCString()); |
13102 } | 12524 } |
13103 } else if (primary->primary().IsClass()) { | 12525 } else if (primary->primary().IsClass()) { |
13104 const Class& type_class = Class::Cast(primary->primary()); | 12526 const Class& type_class = Class::Cast(primary->primary()); |
13105 AbstractType& type = Type::ZoneHandle(Z, | 12527 AbstractType& type = |
13106 Type::New(type_class, TypeArguments::Handle(Z), primary_pos, | 12528 Type::ZoneHandle(Z, Type::New(type_class, TypeArguments::Handle(Z), |
13107 Heap::kOld)); | 12529 primary_pos, Heap::kOld)); |
13108 type ^= ClassFinalizer::FinalizeType( | 12530 type ^= ClassFinalizer::FinalizeType(current_class(), type, |
13109 current_class(), type, ClassFinalizer::kCanonicalize); | 12531 ClassFinalizer::kCanonicalize); |
13110 // Type may be malbounded, but not malformed. | 12532 // Type may be malbounded, but not malformed. |
13111 ASSERT(!type.IsMalformed()); | 12533 ASSERT(!type.IsMalformed()); |
13112 resolved = new(Z) TypeNode(primary_pos, type); | 12534 resolved = new (Z) TypeNode(primary_pos, type); |
13113 } | 12535 } |
13114 } | 12536 } |
13115 return resolved; | 12537 return resolved; |
13116 } | 12538 } |
13117 | 12539 |
13118 | 12540 |
13119 RawAbstractType* Parser::ParseType( | 12541 RawAbstractType* Parser::ParseType( |
13120 ClassFinalizer::FinalizationKind finalization, | 12542 ClassFinalizer::FinalizationKind finalization, |
13121 bool allow_deferred_type, | 12543 bool allow_deferred_type, |
13122 bool consume_unresolved_prefix) { | 12544 bool consume_unresolved_prefix) { |
13123 LibraryPrefix& prefix = LibraryPrefix::Handle(Z); | 12545 LibraryPrefix& prefix = LibraryPrefix::Handle(Z); |
13124 return ParseType(finalization, allow_deferred_type, | 12546 return ParseType(finalization, allow_deferred_type, consume_unresolved_prefix, |
13125 consume_unresolved_prefix, &prefix); | 12547 &prefix); |
13126 } | 12548 } |
13127 | 12549 |
13128 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 12550 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
13129 // finalize it according to the given type finalization mode. Returns prefix. | 12551 // finalize it according to the given type finalization mode. Returns prefix. |
13130 RawAbstractType* Parser::ParseType( | 12552 RawAbstractType* Parser::ParseType( |
13131 ClassFinalizer::FinalizationKind finalization, | 12553 ClassFinalizer::FinalizationKind finalization, |
13132 bool allow_deferred_type, | 12554 bool allow_deferred_type, |
13133 bool consume_unresolved_prefix, | 12555 bool consume_unresolved_prefix, |
13134 LibraryPrefix* prefix) { | 12556 LibraryPrefix* prefix) { |
13135 TRACE_PARSER("ParseType"); | 12557 TRACE_PARSER("ParseType"); |
(...skipping 14 matching lines...) Expand all Loading... |
13150 ExpectToken(Token::kPERIOD); | 12572 ExpectToken(Token::kPERIOD); |
13151 } | 12573 } |
13152 type_name = CurrentLiteral()->raw(); | 12574 type_name = CurrentLiteral()->raw(); |
13153 ConsumeToken(); | 12575 ConsumeToken(); |
13154 | 12576 |
13155 // Check whether we have a malformed qualified type name if the caller | 12577 // Check whether we have a malformed qualified type name if the caller |
13156 // requests to consume unresolved prefix names: | 12578 // requests to consume unresolved prefix names: |
13157 // If we didn't see a valid prefix but the identifier is followed by | 12579 // If we didn't see a valid prefix but the identifier is followed by |
13158 // a period and another identifier, consume the qualified identifier | 12580 // a period and another identifier, consume the qualified identifier |
13159 // and create a malformed type. | 12581 // and create a malformed type. |
13160 if (consume_unresolved_prefix && | 12582 if (consume_unresolved_prefix && prefix->IsNull() && |
13161 prefix->IsNull() && | |
13162 (CurrentToken() == Token::kPERIOD) && | 12583 (CurrentToken() == Token::kPERIOD) && |
13163 (Token::IsIdentifier(LookaheadToken(1)))) { | 12584 (Token::IsIdentifier(LookaheadToken(1)))) { |
13164 if (!is_top_level_ && (current_block_ != NULL)) { | 12585 if (!is_top_level_ && (current_block_ != NULL)) { |
13165 // Add the unresolved prefix name to the list of referenced | 12586 // Add the unresolved prefix name to the list of referenced |
13166 // names of this scope. | 12587 // names of this scope. |
13167 current_block_->scope->AddReferencedName(TokenPos(), type_name); | 12588 current_block_->scope->AddReferencedName(TokenPos(), type_name); |
13168 } | 12589 } |
13169 ConsumeToken(); // Period token. | 12590 ConsumeToken(); // Period token. |
13170 ASSERT(IsIdentifier()); | 12591 ASSERT(IsIdentifier()); |
13171 String& qualified_name = String::Handle(Z, type_name.raw()); | 12592 String& qualified_name = String::Handle(Z, type_name.raw()); |
13172 qualified_name = String::Concat(qualified_name, Symbols::Dot()); | 12593 qualified_name = String::Concat(qualified_name, Symbols::Dot()); |
13173 qualified_name = String::Concat(qualified_name, *CurrentLiteral()); | 12594 qualified_name = String::Concat(qualified_name, *CurrentLiteral()); |
13174 ConsumeToken(); | 12595 ConsumeToken(); |
13175 // The type is malformed. Skip over its type arguments. | 12596 // The type is malformed. Skip over its type arguments. |
13176 ParseTypeArguments(ClassFinalizer::kIgnore); | 12597 ParseTypeArguments(ClassFinalizer::kIgnore); |
13177 return ClassFinalizer::NewFinalizedMalformedType( | 12598 return ClassFinalizer::NewFinalizedMalformedType( |
13178 Error::Handle(Z), // No previous error. | 12599 Error::Handle(Z), // No previous error. |
13179 script_, | 12600 script_, ident_pos, "qualified name '%s' does not refer to a type", |
13180 ident_pos, | |
13181 "qualified name '%s' does not refer to a type", | |
13182 qualified_name.ToCString()); | 12601 qualified_name.ToCString()); |
13183 } | 12602 } |
13184 | 12603 |
13185 // If parsing inside a local scope, check whether the type name | 12604 // If parsing inside a local scope, check whether the type name |
13186 // is shadowed by a local declaration. | 12605 // is shadowed by a local declaration. |
13187 if (!is_top_level_ && | 12606 if (!is_top_level_ && (prefix->IsNull()) && |
13188 (prefix->IsNull()) && | |
13189 ResolveIdentInLocalScope(ident_pos, type_name, NULL, NULL)) { | 12607 ResolveIdentInLocalScope(ident_pos, type_name, NULL, NULL)) { |
13190 // The type is malformed. Skip over its type arguments. | 12608 // The type is malformed. Skip over its type arguments. |
13191 ParseTypeArguments(ClassFinalizer::kIgnore); | 12609 ParseTypeArguments(ClassFinalizer::kIgnore); |
13192 return ClassFinalizer::NewFinalizedMalformedType( | 12610 return ClassFinalizer::NewFinalizedMalformedType( |
13193 Error::Handle(Z), // No previous error. | 12611 Error::Handle(Z), // No previous error. |
13194 script_, | 12612 script_, ident_pos, "using '%s' in this context is invalid", |
13195 ident_pos, | |
13196 "using '%s' in this context is invalid", | |
13197 type_name.ToCString()); | 12613 type_name.ToCString()); |
13198 } | 12614 } |
13199 if ((!FLAG_load_deferred_eagerly || !allow_deferred_type) && | 12615 if ((!FLAG_load_deferred_eagerly || !allow_deferred_type) && |
13200 !prefix->IsNull() && prefix->is_deferred_load()) { | 12616 !prefix->IsNull() && prefix->is_deferred_load()) { |
13201 // If deferred prefixes are allowed but it is not yet loaded, | 12617 // If deferred prefixes are allowed but it is not yet loaded, |
13202 // remember that this function depends on the prefix. | 12618 // remember that this function depends on the prefix. |
13203 if (allow_deferred_type && !prefix->is_loaded()) { | 12619 if (allow_deferred_type && !prefix->is_loaded()) { |
13204 if (parsed_function() != NULL) { | 12620 if (parsed_function() != NULL) { |
13205 parsed_function()->AddDeferredPrefix(*prefix); | 12621 parsed_function()->AddDeferredPrefix(*prefix); |
13206 } | 12622 } |
13207 } | 12623 } |
13208 // If the deferred prefixes are not allowed, or if the prefix is not yet | 12624 // If the deferred prefixes are not allowed, or if the prefix is not yet |
13209 // loaded when finalization is requested, return a malformed type. | 12625 // loaded when finalization is requested, return a malformed type. |
13210 // Otherwise, handle resolution below, as needed. | 12626 // Otherwise, handle resolution below, as needed. |
13211 if (!allow_deferred_type || | 12627 if (!allow_deferred_type || |
13212 (!prefix->is_loaded() | 12628 (!prefix->is_loaded() && |
13213 && (finalization > ClassFinalizer::kResolveTypeParameters))) { | 12629 (finalization > ClassFinalizer::kResolveTypeParameters))) { |
13214 ParseTypeArguments(ClassFinalizer::kIgnore); | 12630 ParseTypeArguments(ClassFinalizer::kIgnore); |
13215 return ClassFinalizer::NewFinalizedMalformedType( | 12631 return ClassFinalizer::NewFinalizedMalformedType( |
13216 Error::Handle(Z), // No previous error. | 12632 Error::Handle(Z), // No previous error. |
13217 script_, | 12633 script_, ident_pos, !prefix->is_loaded() && allow_deferred_type |
13218 ident_pos, | 12634 ? "deferred type '%s.%s' is not yet loaded" |
13219 !prefix->is_loaded() && allow_deferred_type | 12635 : "using deferred type '%s.%s' is invalid", |
13220 ? "deferred type '%s.%s' is not yet loaded" | |
13221 : "using deferred type '%s.%s' is invalid", | |
13222 String::Handle(Z, prefix->name()).ToCString(), | 12636 String::Handle(Z, prefix->name()).ToCString(), |
13223 type_name.ToCString()); | 12637 type_name.ToCString()); |
13224 } | 12638 } |
13225 } | 12639 } |
13226 } | 12640 } |
13227 Object& type_class = Object::Handle(Z); | 12641 Object& type_class = Object::Handle(Z); |
13228 // Leave type_class as null if type finalization mode is kIgnore. | 12642 // Leave type_class as null if type finalization mode is kIgnore. |
13229 if (finalization != ClassFinalizer::kIgnore) { | 12643 if (finalization != ClassFinalizer::kIgnore) { |
13230 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); | 12644 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); |
13231 } | 12645 } |
13232 TypeArguments& type_arguments = TypeArguments::Handle( | 12646 TypeArguments& type_arguments = |
13233 Z, ParseTypeArguments(finalization)); | 12647 TypeArguments::Handle(Z, ParseTypeArguments(finalization)); |
13234 if (finalization == ClassFinalizer::kIgnore) { | 12648 if (finalization == ClassFinalizer::kIgnore) { |
13235 return Type::DynamicType(); | 12649 return Type::DynamicType(); |
13236 } | 12650 } |
13237 AbstractType& type = AbstractType::Handle( | 12651 AbstractType& type = AbstractType::Handle( |
13238 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); | 12652 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); |
13239 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 12653 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
13240 ResolveType(finalization, &type); | 12654 ResolveType(finalization, &type); |
13241 if (finalization >= ClassFinalizer::kCanonicalize) { | 12655 if (finalization >= ClassFinalizer::kCanonicalize) { |
13242 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 12656 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
13243 } | 12657 } |
13244 } | 12658 } |
13245 return type.raw(); | 12659 return type.raw(); |
13246 } | 12660 } |
13247 | 12661 |
13248 | 12662 |
13249 void Parser::CheckConstructorCallTypeArguments( | 12663 void Parser::CheckConstructorCallTypeArguments( |
13250 TokenPosition pos, const Function& constructor, | 12664 TokenPosition pos, |
| 12665 const Function& constructor, |
13251 const TypeArguments& type_arguments) { | 12666 const TypeArguments& type_arguments) { |
13252 if (!type_arguments.IsNull()) { | 12667 if (!type_arguments.IsNull()) { |
13253 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); | 12668 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); |
13254 ASSERT(!constructor_class.IsNull()); | 12669 ASSERT(!constructor_class.IsNull()); |
13255 ASSERT(constructor_class.is_finalized()); | 12670 ASSERT(constructor_class.is_finalized()); |
13256 ASSERT(type_arguments.IsCanonical()); | 12671 ASSERT(type_arguments.IsCanonical()); |
13257 // Do not report the expected vs. actual number of type arguments, because | 12672 // Do not report the expected vs. actual number of type arguments, because |
13258 // the type argument vector is flattened and raw types are allowed. | 12673 // the type argument vector is flattened and raw types are allowed. |
13259 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 12674 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
13260 ReportError(pos, "wrong number of type arguments passed to constructor"); | 12675 ReportError(pos, "wrong number of type arguments passed to constructor"); |
(...skipping 11 matching lines...) Expand all Loading... |
13272 const TypeArguments& type_arguments) { | 12687 const TypeArguments& type_arguments) { |
13273 TRACE_PARSER("ParseListLiteral"); | 12688 TRACE_PARSER("ParseListLiteral"); |
13274 ASSERT(type_pos.IsReal()); | 12689 ASSERT(type_pos.IsReal()); |
13275 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 12690 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
13276 const TokenPosition literal_pos = TokenPos(); | 12691 const TokenPosition literal_pos = TokenPos(); |
13277 | 12692 |
13278 if (is_const) { | 12693 if (is_const) { |
13279 Instance& existing_const = Instance::ZoneHandle(Z); | 12694 Instance& existing_const = Instance::ZoneHandle(Z); |
13280 if (GetCachedConstant(literal_pos, &existing_const)) { | 12695 if (GetCachedConstant(literal_pos, &existing_const)) { |
13281 SkipListLiteral(); | 12696 SkipListLiteral(); |
13282 return new(Z) LiteralNode(literal_pos, existing_const); | 12697 return new (Z) LiteralNode(literal_pos, existing_const); |
13283 } | 12698 } |
13284 } | 12699 } |
13285 | 12700 |
13286 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 12701 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
13287 ConsumeToken(); | 12702 ConsumeToken(); |
13288 | 12703 |
13289 AbstractType& element_type = Type::ZoneHandle(Z, Type::DynamicType()); | 12704 AbstractType& element_type = Type::ZoneHandle(Z, Type::DynamicType()); |
13290 TypeArguments& list_type_arguments = | 12705 TypeArguments& list_type_arguments = |
13291 TypeArguments::ZoneHandle(Z, type_arguments.raw()); | 12706 TypeArguments::ZoneHandle(Z, type_arguments.raw()); |
13292 // If no type argument vector is provided, leave it as null, which is | 12707 // If no type argument vector is provided, leave it as null, which is |
13293 // equivalent to using dynamic as the type argument for the element type. | 12708 // equivalent to using dynamic as the type argument for the element type. |
13294 if (!list_type_arguments.IsNull()) { | 12709 if (!list_type_arguments.IsNull()) { |
13295 ASSERT(list_type_arguments.Length() > 0); | 12710 ASSERT(list_type_arguments.Length() > 0); |
13296 // List literals take a single type argument. | 12711 // List literals take a single type argument. |
13297 if (list_type_arguments.Length() == 1) { | 12712 if (list_type_arguments.Length() == 1) { |
13298 element_type = list_type_arguments.TypeAt(0); | 12713 element_type = list_type_arguments.TypeAt(0); |
13299 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. | 12714 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. |
13300 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. | 12715 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. |
13301 if (element_type.IsDynamicType()) { | 12716 if (element_type.IsDynamicType()) { |
13302 list_type_arguments = TypeArguments::null(); | 12717 list_type_arguments = TypeArguments::null(); |
13303 } else if (is_const && !element_type.IsInstantiated()) { | 12718 } else if (is_const && !element_type.IsInstantiated()) { |
13304 ReportError(type_pos, | 12719 ReportError(type_pos, |
13305 "the type argument of a constant list literal cannot " | 12720 "the type argument of a constant list literal cannot " |
13306 "include a type variable"); | 12721 "include a type variable"); |
13307 } | 12722 } |
13308 } else { | 12723 } else { |
13309 if (I->error_on_bad_type()) { | 12724 if (I->error_on_bad_type()) { |
13310 ReportError(type_pos, | 12725 ReportError(type_pos, |
13311 "a list literal takes one type argument specifying " | 12726 "a list literal takes one type argument specifying " |
13312 "the element type"); | 12727 "the element type"); |
13313 } | 12728 } |
13314 // Ignore type arguments. | 12729 // Ignore type arguments. |
13315 list_type_arguments = TypeArguments::null(); | 12730 list_type_arguments = TypeArguments::null(); |
13316 } | 12731 } |
13317 } | 12732 } |
13318 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); | 12733 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
13319 const Class& array_class = Class::Handle(Z, I->object_store()->array_class()); | 12734 const Class& array_class = Class::Handle(Z, I->object_store()->array_class()); |
13320 Type& type = Type::ZoneHandle(Z, | 12735 Type& type = Type::ZoneHandle( |
13321 Type::New(array_class, list_type_arguments, type_pos, Heap::kOld)); | 12736 Z, Type::New(array_class, list_type_arguments, type_pos, Heap::kOld)); |
13322 type ^= ClassFinalizer::FinalizeType( | 12737 type ^= ClassFinalizer::FinalizeType(current_class(), type, |
13323 current_class(), type, ClassFinalizer::kCanonicalize); | 12738 ClassFinalizer::kCanonicalize); |
13324 GrowableArray<AstNode*> element_list; | 12739 GrowableArray<AstNode*> element_list; |
13325 // Parse the list elements. Note: there may be an optional extra | 12740 // Parse the list elements. Note: there may be an optional extra |
13326 // comma after the last element. | 12741 // comma after the last element. |
13327 if (!is_empty_literal) { | 12742 if (!is_empty_literal) { |
13328 const bool saved_mode = SetAllowFunctionLiterals(true); | 12743 const bool saved_mode = SetAllowFunctionLiterals(true); |
13329 while (CurrentToken() != Token::kRBRACK) { | 12744 while (CurrentToken() != Token::kRBRACK) { |
13330 const TokenPosition element_pos = TokenPos(); | 12745 const TokenPosition element_pos = TokenPos(); |
13331 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 12746 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
13332 if (I->type_checks() && | 12747 if (I->type_checks() && !is_const && !element_type.IsDynamicType()) { |
13333 !is_const && | 12748 element = new (Z) AssignableNode(element_pos, element, element_type, |
13334 !element_type.IsDynamicType()) { | 12749 Symbols::ListLiteralElement()); |
13335 element = new(Z) AssignableNode(element_pos, | |
13336 element, | |
13337 element_type, | |
13338 Symbols::ListLiteralElement()); | |
13339 } | 12750 } |
13340 element_list.Add(element); | 12751 element_list.Add(element); |
13341 if (CurrentToken() == Token::kCOMMA) { | 12752 if (CurrentToken() == Token::kCOMMA) { |
13342 ConsumeToken(); | 12753 ConsumeToken(); |
13343 } else if (CurrentToken() != Token::kRBRACK) { | 12754 } else if (CurrentToken() != Token::kRBRACK) { |
13344 ReportError("comma or ']' expected"); | 12755 ReportError("comma or ']' expected"); |
13345 } | 12756 } |
13346 } | 12757 } |
13347 ExpectToken(Token::kRBRACK); | 12758 ExpectToken(Token::kRBRACK); |
13348 SetAllowFunctionLiterals(saved_mode); | 12759 SetAllowFunctionLiterals(saved_mode); |
13349 } | 12760 } |
13350 | 12761 |
13351 if (is_const) { | 12762 if (is_const) { |
13352 // Allocate and initialize the const list at compile time. | 12763 // Allocate and initialize the const list at compile time. |
13353 if ((element_list.length() == 0) && list_type_arguments.IsNull()) { | 12764 if ((element_list.length() == 0) && list_type_arguments.IsNull()) { |
13354 return new(Z) LiteralNode(literal_pos, Object::empty_array()); | 12765 return new (Z) LiteralNode(literal_pos, Object::empty_array()); |
13355 } | 12766 } |
13356 Array& const_list = Array::ZoneHandle(Z, | 12767 Array& const_list = |
13357 Array::New(element_list.length(), Heap::kOld)); | 12768 Array::ZoneHandle(Z, Array::New(element_list.length(), Heap::kOld)); |
13358 const_list.SetTypeArguments( | 12769 const_list.SetTypeArguments( |
13359 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); | 12770 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); |
13360 Error& bound_error = Error::Handle(Z); | 12771 Error& bound_error = Error::Handle(Z); |
13361 for (int i = 0; i < element_list.length(); i++) { | 12772 for (int i = 0; i < element_list.length(); i++) { |
13362 AstNode* elem = element_list[i]; | 12773 AstNode* elem = element_list[i]; |
13363 // Arguments have been evaluated to a literal value already. | 12774 // Arguments have been evaluated to a literal value already. |
13364 ASSERT(elem->IsLiteralNode()); | 12775 ASSERT(elem->IsLiteralNode()); |
13365 ASSERT(!is_top_level_); // We cannot check unresolved types. | 12776 ASSERT(!is_top_level_); // We cannot check unresolved types. |
13366 if (I->type_checks() && | 12777 if (I->type_checks() && !element_type.IsDynamicType() && |
13367 !element_type.IsDynamicType() && | |
13368 (!elem->AsLiteralNode()->literal().IsNull() && | 12778 (!elem->AsLiteralNode()->literal().IsNull() && |
13369 !elem->AsLiteralNode()->literal().IsInstanceOf( | 12779 !elem->AsLiteralNode()->literal().IsInstanceOf( |
13370 element_type, | 12780 element_type, TypeArguments::Handle(Z), &bound_error))) { |
13371 TypeArguments::Handle(Z), | |
13372 &bound_error))) { | |
13373 // If the failure is due to a bound error, display it instead. | 12781 // If the failure is due to a bound error, display it instead. |
13374 if (!bound_error.IsNull()) { | 12782 if (!bound_error.IsNull()) { |
13375 ReportError(bound_error); | 12783 ReportError(bound_error); |
13376 } else { | 12784 } else { |
13377 ReportError(elem->AsLiteralNode()->token_pos(), | 12785 ReportError( |
13378 "list literal element at index %d must be " | 12786 elem->AsLiteralNode()->token_pos(), |
13379 "a constant of type '%s'", | 12787 "list literal element at index %d must be " |
13380 i, | 12788 "a constant of type '%s'", |
13381 String::Handle(Z, | 12789 i, String::Handle(Z, element_type.UserVisibleName()).ToCString()); |
13382 element_type.UserVisibleName()).ToCString()); | |
13383 } | 12790 } |
13384 } | 12791 } |
13385 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 12792 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
13386 } | 12793 } |
13387 const_list.MakeImmutable(); | 12794 const_list.MakeImmutable(); |
13388 const_list ^= TryCanonicalize(const_list, literal_pos); | 12795 const_list ^= TryCanonicalize(const_list, literal_pos); |
13389 CacheConstantValue(literal_pos, const_list); | 12796 CacheConstantValue(literal_pos, const_list); |
13390 return new(Z) LiteralNode(literal_pos, const_list); | 12797 return new (Z) LiteralNode(literal_pos, const_list); |
13391 } else { | 12798 } else { |
13392 // Factory call at runtime. | 12799 // Factory call at runtime. |
13393 const Class& factory_class = | 12800 const Class& factory_class = |
13394 Class::Handle(Z, Library::LookupCoreClass(Symbols::List())); | 12801 Class::Handle(Z, Library::LookupCoreClass(Symbols::List())); |
13395 ASSERT(!factory_class.IsNull()); | 12802 ASSERT(!factory_class.IsNull()); |
13396 const Function& factory_method = Function::ZoneHandle(Z, | 12803 const Function& factory_method = Function::ZoneHandle( |
13397 factory_class.LookupFactory( | 12804 Z, factory_class.LookupFactory( |
13398 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 12805 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
13399 ASSERT(!factory_method.IsNull()); | 12806 ASSERT(!factory_method.IsNull()); |
13400 if (!list_type_arguments.IsNull() && | 12807 if (!list_type_arguments.IsNull() && |
13401 !list_type_arguments.IsInstantiated() && | 12808 !list_type_arguments.IsInstantiated() && (FunctionLevel() > 0)) { |
13402 (FunctionLevel() > 0)) { | |
13403 // Make sure that the instantiator is captured. | 12809 // Make sure that the instantiator is captured. |
13404 CaptureInstantiator(); | 12810 CaptureInstantiator(); |
13405 } | 12811 } |
13406 TypeArguments& factory_type_args = | 12812 TypeArguments& factory_type_args = |
13407 TypeArguments::ZoneHandle(Z, list_type_arguments.raw()); | 12813 TypeArguments::ZoneHandle(Z, list_type_arguments.raw()); |
13408 // If the factory class extends other parameterized classes, adjust the | 12814 // If the factory class extends other parameterized classes, adjust the |
13409 // type argument vector. | 12815 // type argument vector. |
13410 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { | 12816 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { |
13411 ASSERT(factory_type_args.Length() == 1); | 12817 ASSERT(factory_type_args.Length() == 1); |
13412 Type& factory_type = Type::Handle(Z, Type::New( | 12818 Type& factory_type = Type::Handle( |
13413 factory_class, factory_type_args, type_pos, Heap::kOld)); | 12819 Z, Type::New(factory_class, factory_type_args, type_pos, Heap::kOld)); |
13414 factory_type ^= ClassFinalizer::FinalizeType( | 12820 factory_type ^= ClassFinalizer::FinalizeType( |
13415 current_class(), factory_type, ClassFinalizer::kFinalize); | 12821 current_class(), factory_type, ClassFinalizer::kFinalize); |
13416 factory_type_args = factory_type.arguments(); | 12822 factory_type_args = factory_type.arguments(); |
13417 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 12823 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
13418 } | 12824 } |
13419 factory_type_args = factory_type_args.Canonicalize(); | 12825 factory_type_args = factory_type_args.Canonicalize(); |
13420 ArgumentListNode* factory_param = new(Z) ArgumentListNode( | 12826 ArgumentListNode* factory_param = new (Z) ArgumentListNode(literal_pos); |
13421 literal_pos); | |
13422 if (element_list.length() == 0) { | 12827 if (element_list.length() == 0) { |
13423 LiteralNode* empty_array_literal = | 12828 LiteralNode* empty_array_literal = |
13424 new(Z) LiteralNode(TokenPos(), Object::empty_array()); | 12829 new (Z) LiteralNode(TokenPos(), Object::empty_array()); |
13425 factory_param->Add(empty_array_literal); | 12830 factory_param->Add(empty_array_literal); |
13426 } else { | 12831 } else { |
13427 ArrayNode* list = new(Z) ArrayNode(TokenPos(), type, element_list); | 12832 ArrayNode* list = new (Z) ArrayNode(TokenPos(), type, element_list); |
13428 factory_param->Add(list); | 12833 factory_param->Add(list); |
13429 } | 12834 } |
13430 return CreateConstructorCallNode(literal_pos, | 12835 return CreateConstructorCallNode(literal_pos, factory_type_args, |
13431 factory_type_args, | 12836 factory_method, factory_param); |
13432 factory_method, | |
13433 factory_param); | |
13434 } | 12837 } |
13435 } | 12838 } |
13436 | 12839 |
13437 | 12840 |
13438 ConstructorCallNode* Parser::CreateConstructorCallNode( | 12841 ConstructorCallNode* Parser::CreateConstructorCallNode( |
13439 TokenPosition token_pos, | 12842 TokenPosition token_pos, |
13440 const TypeArguments& type_arguments, | 12843 const TypeArguments& type_arguments, |
13441 const Function& constructor, | 12844 const Function& constructor, |
13442 ArgumentListNode* arguments) { | 12845 ArgumentListNode* arguments) { |
13443 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 12846 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
13444 EnsureExpressionTemp(); | 12847 EnsureExpressionTemp(); |
13445 } | 12848 } |
13446 return new(Z) ConstructorCallNode( | 12849 return new (Z) |
13447 token_pos, type_arguments, constructor, arguments); | 12850 ConstructorCallNode(token_pos, type_arguments, constructor, arguments); |
13448 } | 12851 } |
13449 | 12852 |
13450 | 12853 |
13451 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, | 12854 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, |
13452 bool is_const, | 12855 bool is_const, |
13453 AstNode* key, | 12856 AstNode* key, |
13454 AstNode* value) { | 12857 AstNode* value) { |
13455 if (is_const) { | 12858 if (is_const) { |
13456 ASSERT(key->IsLiteralNode()); | 12859 ASSERT(key->IsLiteralNode()); |
13457 const Instance& new_key = key->AsLiteralNode()->literal(); | 12860 const Instance& new_key = key->AsLiteralNode()->literal(); |
(...skipping 20 matching lines...) Expand all Loading... |
13478 const TypeArguments& type_arguments) { | 12881 const TypeArguments& type_arguments) { |
13479 TRACE_PARSER("ParseMapLiteral"); | 12882 TRACE_PARSER("ParseMapLiteral"); |
13480 ASSERT(type_pos.IsReal()); | 12883 ASSERT(type_pos.IsReal()); |
13481 ASSERT(CurrentToken() == Token::kLBRACE); | 12884 ASSERT(CurrentToken() == Token::kLBRACE); |
13482 const TokenPosition literal_pos = TokenPos(); | 12885 const TokenPosition literal_pos = TokenPos(); |
13483 | 12886 |
13484 if (is_const) { | 12887 if (is_const) { |
13485 Instance& existing_const = Instance::ZoneHandle(Z); | 12888 Instance& existing_const = Instance::ZoneHandle(Z); |
13486 if (GetCachedConstant(literal_pos, &existing_const)) { | 12889 if (GetCachedConstant(literal_pos, &existing_const)) { |
13487 SkipMapLiteral(); | 12890 SkipMapLiteral(); |
13488 return new(Z) LiteralNode(literal_pos, existing_const); | 12891 return new (Z) LiteralNode(literal_pos, existing_const); |
13489 } | 12892 } |
13490 } | 12893 } |
13491 | 12894 |
13492 ConsumeToken(); // Opening brace. | 12895 ConsumeToken(); // Opening brace. |
13493 AbstractType& key_type = Type::ZoneHandle(Z, Type::DynamicType()); | 12896 AbstractType& key_type = Type::ZoneHandle(Z, Type::DynamicType()); |
13494 AbstractType& value_type = Type::ZoneHandle(Z, Type::DynamicType()); | 12897 AbstractType& value_type = Type::ZoneHandle(Z, Type::DynamicType()); |
13495 TypeArguments& map_type_arguments = | 12898 TypeArguments& map_type_arguments = |
13496 TypeArguments::ZoneHandle(Z, type_arguments.raw()); | 12899 TypeArguments::ZoneHandle(Z, type_arguments.raw()); |
13497 // If no type argument vector is provided, leave it as null, which is | 12900 // If no type argument vector is provided, leave it as null, which is |
13498 // equivalent to using dynamic as the type argument for the both key and value | 12901 // equivalent to using dynamic as the type argument for the both key and value |
(...skipping 28 matching lines...) Expand all Loading... |
13527 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 12930 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
13528 map_type_arguments ^= map_type_arguments.Canonicalize(); | 12931 map_type_arguments ^= map_type_arguments.Canonicalize(); |
13529 | 12932 |
13530 GrowableArray<AstNode*> kv_pairs_list; | 12933 GrowableArray<AstNode*> kv_pairs_list; |
13531 // Parse the map entries. Note: there may be an optional extra | 12934 // Parse the map entries. Note: there may be an optional extra |
13532 // comma after the last entry. | 12935 // comma after the last entry. |
13533 while (CurrentToken() != Token::kRBRACE) { | 12936 while (CurrentToken() != Token::kRBRACE) { |
13534 const bool saved_mode = SetAllowFunctionLiterals(true); | 12937 const bool saved_mode = SetAllowFunctionLiterals(true); |
13535 const TokenPosition key_pos = TokenPos(); | 12938 const TokenPosition key_pos = TokenPos(); |
13536 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 12939 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
13537 if (I->type_checks() && | 12940 if (I->type_checks() && !is_const && !key_type.IsDynamicType()) { |
13538 !is_const && | 12941 key = new (Z) |
13539 !key_type.IsDynamicType()) { | 12942 AssignableNode(key_pos, key, key_type, Symbols::ListLiteralElement()); |
13540 key = new(Z) AssignableNode( | |
13541 key_pos, key, key_type, Symbols::ListLiteralElement()); | |
13542 } | 12943 } |
13543 if (is_const) { | 12944 if (is_const) { |
13544 ASSERT(key->IsLiteralNode()); | 12945 ASSERT(key->IsLiteralNode()); |
13545 const Instance& key_value = key->AsLiteralNode()->literal(); | 12946 const Instance& key_value = key->AsLiteralNode()->literal(); |
13546 if (key_value.IsDouble()) { | 12947 if (key_value.IsDouble()) { |
13547 ReportError(key_pos, "key value must not be of type double"); | 12948 ReportError(key_pos, "key value must not be of type double"); |
13548 } | 12949 } |
13549 if (!key_value.IsInteger() && | 12950 if (!key_value.IsInteger() && !key_value.IsString() && |
13550 !key_value.IsString() && | |
13551 (key_value.clazz() != I->object_store()->symbol_class()) && | 12951 (key_value.clazz() != I->object_store()->symbol_class()) && |
13552 ImplementsEqualOperator(Z, key_value)) { | 12952 ImplementsEqualOperator(Z, key_value)) { |
13553 ReportError(key_pos, "key value must not implement operator =="); | 12953 ReportError(key_pos, "key value must not implement operator =="); |
13554 } | 12954 } |
13555 } | 12955 } |
13556 ExpectToken(Token::kCOLON); | 12956 ExpectToken(Token::kCOLON); |
13557 const TokenPosition value_pos = TokenPos(); | 12957 const TokenPosition value_pos = TokenPos(); |
13558 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 12958 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
13559 SetAllowFunctionLiterals(saved_mode); | 12959 SetAllowFunctionLiterals(saved_mode); |
13560 if (I->type_checks() && | 12960 if (I->type_checks() && !is_const && !value_type.IsDynamicType()) { |
13561 !is_const && | 12961 value = new (Z) AssignableNode(value_pos, value, value_type, |
13562 !value_type.IsDynamicType()) { | 12962 Symbols::ListLiteralElement()); |
13563 value = new(Z) AssignableNode( | |
13564 value_pos, value, value_type, Symbols::ListLiteralElement()); | |
13565 } | 12963 } |
13566 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 12964 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
13567 | 12965 |
13568 if (CurrentToken() == Token::kCOMMA) { | 12966 if (CurrentToken() == Token::kCOMMA) { |
13569 ConsumeToken(); | 12967 ConsumeToken(); |
13570 } else if (CurrentToken() != Token::kRBRACE) { | 12968 } else if (CurrentToken() != Token::kRBRACE) { |
13571 ReportError("comma or '}' expected"); | 12969 ReportError("comma or '}' expected"); |
13572 } | 12970 } |
13573 } | 12971 } |
13574 ASSERT(kv_pairs_list.length() % 2 == 0); | 12972 ASSERT(kv_pairs_list.length() % 2 == 0); |
(...skipping 18 matching lines...) Expand all Loading... |
13593 if ((i % 2) == 0) { | 12991 if ((i % 2) == 0) { |
13594 // Check key type. | 12992 // Check key type. |
13595 arg_type = key_type.raw(); | 12993 arg_type = key_type.raw(); |
13596 } else { | 12994 } else { |
13597 // Check value type. | 12995 // Check value type. |
13598 arg_type = value_type.raw(); | 12996 arg_type = value_type.raw(); |
13599 } | 12997 } |
13600 if (!arg_type.IsDynamicType() && | 12998 if (!arg_type.IsDynamicType() && |
13601 (!arg->AsLiteralNode()->literal().IsNull() && | 12999 (!arg->AsLiteralNode()->literal().IsNull() && |
13602 !arg->AsLiteralNode()->literal().IsInstanceOf( | 13000 !arg->AsLiteralNode()->literal().IsInstanceOf( |
13603 arg_type, | 13001 arg_type, Object::null_type_arguments(), &bound_error))) { |
13604 Object::null_type_arguments(), | |
13605 &bound_error))) { | |
13606 // If the failure is due to a bound error, display it. | 13002 // If the failure is due to a bound error, display it. |
13607 if (!bound_error.IsNull()) { | 13003 if (!bound_error.IsNull()) { |
13608 ReportError(bound_error); | 13004 ReportError(bound_error); |
13609 } else { | 13005 } else { |
13610 ReportError(arg->AsLiteralNode()->token_pos(), | 13006 ReportError( |
13611 "map literal %s at index %d must be " | 13007 arg->AsLiteralNode()->token_pos(), |
13612 "a constant of type '%s'", | 13008 "map literal %s at index %d must be " |
13613 ((i % 2) == 0) ? "key" : "value", | 13009 "a constant of type '%s'", |
13614 i >> 1, | 13010 ((i % 2) == 0) ? "key" : "value", i >> 1, |
13615 String::Handle(Z, | 13011 String::Handle(Z, arg_type.UserVisibleName()).ToCString()); |
13616 arg_type.UserVisibleName()).ToCString()); | |
13617 } | 13012 } |
13618 } | 13013 } |
13619 } | 13014 } |
13620 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 13015 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
13621 } | 13016 } |
13622 key_value_array.MakeImmutable(); | 13017 key_value_array.MakeImmutable(); |
13623 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); | 13018 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); |
13624 | 13019 |
13625 // Construct the map object. | 13020 // Construct the map object. |
13626 const Class& immutable_map_class = Class::Handle(Z, | 13021 const Class& immutable_map_class = |
13627 Library::LookupCoreClass(Symbols::ImmutableMap())); | 13022 Class::Handle(Z, Library::LookupCoreClass(Symbols::ImmutableMap())); |
13628 ASSERT(!immutable_map_class.IsNull()); | 13023 ASSERT(!immutable_map_class.IsNull()); |
13629 // If the immutable map class extends other parameterized classes, we need | 13024 // If the immutable map class extends other parameterized classes, we need |
13630 // to adjust the type argument vector. This is currently not the case. | 13025 // to adjust the type argument vector. This is currently not the case. |
13631 ASSERT(immutable_map_class.NumTypeArguments() == 2); | 13026 ASSERT(immutable_map_class.NumTypeArguments() == 2); |
13632 ArgumentListNode* constr_args = new(Z) ArgumentListNode(TokenPos()); | 13027 ArgumentListNode* constr_args = new (Z) ArgumentListNode(TokenPos()); |
13633 constr_args->Add(new(Z) LiteralNode(literal_pos, key_value_array)); | 13028 constr_args->Add(new (Z) LiteralNode(literal_pos, key_value_array)); |
13634 const Function& map_constr = | 13029 const Function& map_constr = Function::ZoneHandle( |
13635 Function::ZoneHandle(Z, immutable_map_class.LookupConstructor( | 13030 Z, immutable_map_class.LookupConstructor(Library::PrivateCoreLibName( |
13636 Library::PrivateCoreLibName(Symbols::ImmutableMapConstructor()))); | 13031 Symbols::ImmutableMapConstructor()))); |
13637 ASSERT(!map_constr.IsNull()); | 13032 ASSERT(!map_constr.IsNull()); |
13638 const Object& constructor_result = Object::Handle(Z, | 13033 const Object& constructor_result = Object::Handle( |
13639 EvaluateConstConstructorCall(immutable_map_class, | 13034 Z, EvaluateConstConstructorCall(immutable_map_class, map_type_arguments, |
13640 map_type_arguments, | 13035 map_constr, constr_args)); |
13641 map_constr, | |
13642 constr_args)); | |
13643 if (constructor_result.IsUnhandledException()) { | 13036 if (constructor_result.IsUnhandledException()) { |
13644 ReportErrors(Error::Cast(constructor_result), | 13037 ReportErrors(Error::Cast(constructor_result), script_, literal_pos, |
13645 script_, literal_pos, | |
13646 "error executing const Map constructor"); | 13038 "error executing const Map constructor"); |
13647 } else { | 13039 } else { |
13648 const Instance& const_instance = Instance::Cast(constructor_result); | 13040 const Instance& const_instance = Instance::Cast(constructor_result); |
13649 CacheConstantValue(literal_pos, const_instance); | 13041 CacheConstantValue(literal_pos, const_instance); |
13650 return new(Z) LiteralNode( | 13042 return new (Z) LiteralNode(literal_pos, |
13651 literal_pos, Instance::ZoneHandle(Z, const_instance.raw())); | 13043 Instance::ZoneHandle(Z, const_instance.raw())); |
13652 } | 13044 } |
13653 } else { | 13045 } else { |
13654 // Factory call at runtime. | 13046 // Factory call at runtime. |
13655 const Class& factory_class = | 13047 const Class& factory_class = |
13656 Class::Handle(Z, Library::LookupCoreClass(Symbols::Map())); | 13048 Class::Handle(Z, Library::LookupCoreClass(Symbols::Map())); |
13657 ASSERT(!factory_class.IsNull()); | 13049 ASSERT(!factory_class.IsNull()); |
13658 const Function& factory_method = Function::ZoneHandle(Z, | 13050 const Function& factory_method = Function::ZoneHandle( |
13659 factory_class.LookupFactory( | 13051 Z, factory_class.LookupFactory( |
13660 Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); | 13052 Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); |
13661 ASSERT(!factory_method.IsNull()); | 13053 ASSERT(!factory_method.IsNull()); |
13662 if (!map_type_arguments.IsNull() && | 13054 if (!map_type_arguments.IsNull() && !map_type_arguments.IsInstantiated() && |
13663 !map_type_arguments.IsInstantiated() && | |
13664 (FunctionLevel() > 0)) { | 13055 (FunctionLevel() > 0)) { |
13665 // Make sure that the instantiator is captured. | 13056 // Make sure that the instantiator is captured. |
13666 CaptureInstantiator(); | 13057 CaptureInstantiator(); |
13667 } | 13058 } |
13668 TypeArguments& factory_type_args = | 13059 TypeArguments& factory_type_args = |
13669 TypeArguments::ZoneHandle(Z, map_type_arguments.raw()); | 13060 TypeArguments::ZoneHandle(Z, map_type_arguments.raw()); |
13670 // If the factory class extends other parameterized classes, adjust the | 13061 // If the factory class extends other parameterized classes, adjust the |
13671 // type argument vector. | 13062 // type argument vector. |
13672 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) { | 13063 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) { |
13673 ASSERT(factory_type_args.Length() == 2); | 13064 ASSERT(factory_type_args.Length() == 2); |
13674 Type& factory_type = Type::Handle(Z, Type::New( | 13065 Type& factory_type = Type::Handle( |
13675 factory_class, factory_type_args, type_pos, Heap::kOld)); | 13066 Z, Type::New(factory_class, factory_type_args, type_pos, Heap::kOld)); |
13676 factory_type ^= ClassFinalizer::FinalizeType( | 13067 factory_type ^= ClassFinalizer::FinalizeType( |
13677 current_class(), factory_type, ClassFinalizer::kFinalize); | 13068 current_class(), factory_type, ClassFinalizer::kFinalize); |
13678 factory_type_args = factory_type.arguments(); | 13069 factory_type_args = factory_type.arguments(); |
13679 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 13070 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
13680 } | 13071 } |
13681 factory_type_args = factory_type_args.Canonicalize(); | 13072 factory_type_args = factory_type_args.Canonicalize(); |
13682 ArgumentListNode* factory_param = new(Z) ArgumentListNode(literal_pos); | 13073 ArgumentListNode* factory_param = new (Z) ArgumentListNode(literal_pos); |
13683 // The kv_pair array is temporary and of element type dynamic. It is passed | 13074 // The kv_pair array is temporary and of element type dynamic. It is passed |
13684 // to the factory to initialize a properly typed map. Pass a pre-allocated | 13075 // to the factory to initialize a properly typed map. Pass a pre-allocated |
13685 // array for the common empty map literal case. | 13076 // array for the common empty map literal case. |
13686 if (kv_pairs_list.length() == 0) { | 13077 if (kv_pairs_list.length() == 0) { |
13687 LiteralNode* empty_array_literal = | 13078 LiteralNode* empty_array_literal = |
13688 new(Z) LiteralNode(TokenPos(), Object::empty_array()); | 13079 new (Z) LiteralNode(TokenPos(), Object::empty_array()); |
13689 factory_param->Add(empty_array_literal); | 13080 factory_param->Add(empty_array_literal); |
13690 } else { | 13081 } else { |
13691 ArrayNode* kv_pairs = new(Z) ArrayNode( | 13082 ArrayNode* kv_pairs = new (Z) ArrayNode( |
13692 TokenPos(), | 13083 TokenPos(), Type::ZoneHandle(Z, Type::ArrayType()), kv_pairs_list); |
13693 Type::ZoneHandle(Z, Type::ArrayType()), | |
13694 kv_pairs_list); | |
13695 factory_param->Add(kv_pairs); | 13084 factory_param->Add(kv_pairs); |
13696 } | 13085 } |
13697 | 13086 |
13698 return CreateConstructorCallNode(literal_pos, | 13087 return CreateConstructorCallNode(literal_pos, factory_type_args, |
13699 factory_type_args, | 13088 factory_method, factory_param); |
13700 factory_method, | |
13701 factory_param); | |
13702 } | 13089 } |
13703 UNREACHABLE(); | 13090 UNREACHABLE(); |
13704 return NULL; | 13091 return NULL; |
13705 } | 13092 } |
13706 | 13093 |
13707 | 13094 |
13708 AstNode* Parser::ParseCompoundLiteral() { | 13095 AstNode* Parser::ParseCompoundLiteral() { |
13709 TRACE_PARSER("ParseCompoundLiteral"); | 13096 TRACE_PARSER("ParseCompoundLiteral"); |
13710 bool is_const = false; | 13097 bool is_const = false; |
13711 if (CurrentToken() == Token::kCONST) { | 13098 if (CurrentToken() == Token::kCONST) { |
13712 is_const = true; | 13099 is_const = true; |
13713 ConsumeToken(); | 13100 ConsumeToken(); |
13714 } | 13101 } |
13715 const TokenPosition type_pos = TokenPos(); | 13102 const TokenPosition type_pos = TokenPos(); |
13716 TypeArguments& type_arguments = TypeArguments::Handle(Z, | 13103 TypeArguments& type_arguments = TypeArguments::Handle( |
13717 ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 13104 Z, ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
13718 // Malformed type arguments are mapped to dynamic, so we will not encounter | 13105 // Malformed type arguments are mapped to dynamic, so we will not encounter |
13719 // them here. | 13106 // them here. |
13720 // Map and List interfaces do not declare bounds on their type parameters, so | 13107 // Map and List interfaces do not declare bounds on their type parameters, so |
13721 // we will not see malbounded type arguments here. | 13108 // we will not see malbounded type arguments here. |
13722 AstNode* primary = NULL; | 13109 AstNode* primary = NULL; |
13723 if ((CurrentToken() == Token::kLBRACK) || | 13110 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { |
13724 (CurrentToken() == Token::kINDEX)) { | |
13725 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 13111 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
13726 } else if (CurrentToken() == Token::kLBRACE) { | 13112 } else if (CurrentToken() == Token::kLBRACE) { |
13727 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 13113 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
13728 } else { | 13114 } else { |
13729 UnexpectedToken(); | 13115 UnexpectedToken(); |
13730 } | 13116 } |
13731 return primary; | 13117 return primary; |
13732 } | 13118 } |
13733 | 13119 |
13734 | 13120 |
(...skipping 16 matching lines...) Expand all Loading... |
13751 } else if (Token::CanBeOverloaded(CurrentToken())) { | 13137 } else if (Token::CanBeOverloaded(CurrentToken())) { |
13752 symbol = Symbols::Token(CurrentToken()).raw(); | 13138 symbol = Symbols::Token(CurrentToken()).raw(); |
13753 ConsumeToken(); | 13139 ConsumeToken(); |
13754 } else { | 13140 } else { |
13755 ReportError("illegal symbol literal"); | 13141 ReportError("illegal symbol literal"); |
13756 } | 13142 } |
13757 ASSERT(symbol.IsSymbol()); | 13143 ASSERT(symbol.IsSymbol()); |
13758 | 13144 |
13759 Instance& symbol_instance = Instance::ZoneHandle(Z); | 13145 Instance& symbol_instance = Instance::ZoneHandle(Z); |
13760 if (GetCachedConstant(symbol_pos, &symbol_instance)) { | 13146 if (GetCachedConstant(symbol_pos, &symbol_instance)) { |
13761 return new(Z) LiteralNode(symbol_pos, symbol_instance); | 13147 return new (Z) LiteralNode(symbol_pos, symbol_instance); |
13762 } | 13148 } |
13763 | 13149 |
13764 // Call Symbol class constructor to create a symbol instance. | 13150 // Call Symbol class constructor to create a symbol instance. |
13765 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class()); | 13151 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class()); |
13766 ASSERT(!symbol_class.IsNull()); | 13152 ASSERT(!symbol_class.IsNull()); |
13767 ArgumentListNode* constr_args = new(Z) ArgumentListNode(symbol_pos); | 13153 ArgumentListNode* constr_args = new (Z) ArgumentListNode(symbol_pos); |
13768 constr_args->Add(new(Z) LiteralNode(symbol_pos, symbol)); | 13154 constr_args->Add(new (Z) LiteralNode(symbol_pos, symbol)); |
13769 const Function& constr = Function::ZoneHandle(Z, | 13155 const Function& constr = Function::ZoneHandle( |
13770 symbol_class.LookupConstructor(Symbols::SymbolCtor())); | 13156 Z, symbol_class.LookupConstructor(Symbols::SymbolCtor())); |
13771 ASSERT(!constr.IsNull()); | 13157 ASSERT(!constr.IsNull()); |
13772 const Object& result = Object::Handle(Z, | 13158 const Object& result = Object::Handle( |
13773 EvaluateConstConstructorCall(symbol_class, | 13159 Z, EvaluateConstConstructorCall(symbol_class, TypeArguments::Handle(Z), |
13774 TypeArguments::Handle(Z), | 13160 constr, constr_args)); |
13775 constr, | |
13776 constr_args)); | |
13777 if (result.IsUnhandledException()) { | 13161 if (result.IsUnhandledException()) { |
13778 ReportErrors(Error::Cast(result), | 13162 ReportErrors(Error::Cast(result), script_, symbol_pos, |
13779 script_, symbol_pos, | |
13780 "error executing const Symbol constructor"); | 13163 "error executing const Symbol constructor"); |
13781 } | 13164 } |
13782 symbol_instance ^= result.raw(); | 13165 symbol_instance ^= result.raw(); |
13783 CacheConstantValue(symbol_pos, symbol_instance); | 13166 CacheConstantValue(symbol_pos, symbol_instance); |
13784 return new(Z) LiteralNode(symbol_pos, symbol_instance); | 13167 return new (Z) LiteralNode(symbol_pos, symbol_instance); |
13785 } | 13168 } |
13786 | 13169 |
13787 | 13170 |
13788 RawFunction* Parser::BuildConstructorClosureFunction( | 13171 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, |
13789 const Function& ctr, TokenPosition token_pos) { | 13172 TokenPosition token_pos) { |
13790 ASSERT(ctr.kind() == RawFunction::kConstructor); | 13173 ASSERT(ctr.kind() == RawFunction::kConstructor); |
13791 Function& closure = Function::Handle(Z); | 13174 Function& closure = Function::Handle(Z); |
13792 closure = I->LookupClosureFunction(innermost_function(), token_pos); | 13175 closure = I->LookupClosureFunction(innermost_function(), token_pos); |
13793 if (!closure.IsNull()) { | 13176 if (!closure.IsNull()) { |
13794 ASSERT(closure.IsConstructorClosureFunction()); | 13177 ASSERT(closure.IsConstructorClosureFunction()); |
13795 return closure.raw(); | 13178 return closure.raw(); |
13796 } | 13179 } |
13797 | 13180 |
13798 String& closure_name = String::Handle(Z, ctr.name()); | 13181 String& closure_name = String::Handle(Z, ctr.name()); |
13799 closure_name = Symbols::FromConcat(T, | 13182 closure_name = |
13800 Symbols::ConstructorClosurePrefix(), closure_name); | 13183 Symbols::FromConcat(T, Symbols::ConstructorClosurePrefix(), closure_name); |
13801 | 13184 |
13802 ParamList params; | 13185 ParamList params; |
13803 params.AddFinalParameter(token_pos, | 13186 params.AddFinalParameter(token_pos, &Symbols::ClosureParameter(), |
13804 &Symbols::ClosureParameter(), | |
13805 &Object::dynamic_type()); | 13187 &Object::dynamic_type()); |
13806 | 13188 |
13807 ParseFormalParameters(ctr, ¶ms); | 13189 ParseFormalParameters(ctr, ¶ms); |
13808 // Per language spec, the type of the closure parameters is dynamic. | 13190 // Per language spec, the type of the closure parameters is dynamic. |
13809 // Replace the types parsed from the constructor. | 13191 // Replace the types parsed from the constructor. |
13810 params.EraseParameterTypes(); | 13192 params.EraseParameterTypes(); |
13811 | 13193 |
13812 closure = Function::NewClosureFunction(closure_name, | 13194 closure = Function::NewClosureFunction(closure_name, innermost_function(), |
13813 innermost_function(), | |
13814 token_pos); | 13195 token_pos); |
13815 closure.set_is_generated_body(true); | 13196 closure.set_is_generated_body(true); |
13816 closure.set_is_debuggable(false); | 13197 closure.set_is_debuggable(false); |
13817 closure.set_is_visible(false); | 13198 closure.set_is_visible(false); |
13818 closure.set_result_type(Object::dynamic_type()); | 13199 closure.set_result_type(Object::dynamic_type()); |
13819 AddFormalParamsToFunction(¶ms, closure); | 13200 AddFormalParamsToFunction(¶ms, closure); |
13820 | 13201 |
13821 // Finalize function type. | 13202 // Finalize function type. |
13822 Type& signature_type = Type::Handle(Z, closure.SignatureType()); | 13203 Type& signature_type = Type::Handle(Z, closure.SignatureType()); |
13823 signature_type ^= ClassFinalizer::FinalizeType( | 13204 signature_type ^= ClassFinalizer::FinalizeType( |
13824 current_class(), signature_type, ClassFinalizer::kCanonicalize); | 13205 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
13825 closure.SetSignatureType(signature_type); | 13206 closure.SetSignatureType(signature_type); |
13826 // Finalization would be premature when top-level parsing. | 13207 // Finalization would be premature when top-level parsing. |
13827 ASSERT(!is_top_level_); | 13208 ASSERT(!is_top_level_); |
13828 return closure.raw(); | 13209 return closure.raw(); |
13829 } | 13210 } |
13830 | 13211 |
13831 | 13212 |
13832 static String& BuildConstructorName(Thread* thread, | 13213 static String& BuildConstructorName(Thread* thread, |
13833 const String& type_class_name, | 13214 const String& type_class_name, |
13834 const String* named_constructor) { | 13215 const String* named_constructor) { |
13835 // By convention, the static function implementing a named constructor 'C' | 13216 // By convention, the static function implementing a named constructor 'C' |
13836 // for class 'A' is labeled 'A.C', and the static function implementing the | 13217 // for class 'A' is labeled 'A.C', and the static function implementing the |
13837 // unnamed constructor for class 'A' is labeled 'A.'. | 13218 // unnamed constructor for class 'A' is labeled 'A.'. |
13838 // This convention prevents users from explicitly calling constructors. | 13219 // This convention prevents users from explicitly calling constructors. |
13839 Zone* zone = thread->zone(); | 13220 Zone* zone = thread->zone(); |
13840 String& constructor_name = String::Handle(zone, | 13221 String& constructor_name = |
13841 Symbols::FromDot(thread, type_class_name)); | 13222 String::Handle(zone, Symbols::FromDot(thread, type_class_name)); |
13842 if (named_constructor != NULL) { | 13223 if (named_constructor != NULL) { |
13843 constructor_name = | 13224 constructor_name = |
13844 Symbols::FromConcat(thread, constructor_name, *named_constructor); | 13225 Symbols::FromConcat(thread, constructor_name, *named_constructor); |
13845 } | 13226 } |
13846 return constructor_name; | 13227 return constructor_name; |
13847 } | 13228 } |
13848 | 13229 |
13849 | 13230 |
13850 // Parse a primary expression of the form new T# or new T#m. | 13231 // Parse a primary expression of the form new T# or new T#m. |
13851 // Current token position is after the keyword new. Extracts the | 13232 // Current token position is after the keyword new. Extracts the |
13852 // anonymous or named constructor and type arguments. | 13233 // anonymous or named constructor and type arguments. |
13853 // Note that type type T has already been parsed before | 13234 // Note that type type T has already been parsed before |
13854 // (by ParseNewOperator()) and is guaranteed to be well-formed, | 13235 // (by ParseNewOperator()) and is guaranteed to be well-formed, |
13855 // and the constructor is known to exist. | 13236 // and the constructor is known to exist. |
13856 void Parser::ParseConstructorClosurization(Function* constructor, | 13237 void Parser::ParseConstructorClosurization(Function* constructor, |
13857 TypeArguments* type_arguments) { | 13238 TypeArguments* type_arguments) { |
13858 *constructor = Function::null(); | 13239 *constructor = Function::null(); |
13859 *type_arguments = TypeArguments::null(); | 13240 *type_arguments = TypeArguments::null(); |
13860 const Token::Kind la3 = LookaheadToken(3); | 13241 const Token::Kind la3 = LookaheadToken(3); |
13861 const bool consume_unresolved_prefix = | 13242 const bool consume_unresolved_prefix = |
13862 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | 13243 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); |
13863 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 13244 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
13864 AbstractType& type = AbstractType::Handle(Z, | 13245 AbstractType& type = |
13865 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 13246 AbstractType::Handle(Z, ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
13866 true, // allow deferred type | 13247 true, // allow deferred type |
13867 consume_unresolved_prefix, | 13248 consume_unresolved_prefix, &prefix)); |
13868 &prefix)); | |
13869 // A constructor tear-off closure can only have been created for a | 13249 // A constructor tear-off closure can only have been created for a |
13870 // type that is loaded. | 13250 // type that is loaded. |
13871 ASSERT(prefix.IsNull() || prefix.is_loaded()); | 13251 ASSERT(prefix.IsNull() || prefix.is_loaded()); |
13872 ASSERT(!type.IsMalformed() && !type.IsTypeParameter()); | 13252 ASSERT(!type.IsMalformed() && !type.IsTypeParameter()); |
13873 ExpectToken(Token::kHASH); | 13253 ExpectToken(Token::kHASH); |
13874 String* named_constructor = NULL; | 13254 String* named_constructor = NULL; |
13875 if (IsIdentifier()) { | 13255 if (IsIdentifier()) { |
13876 named_constructor = CurrentLiteral(); | 13256 named_constructor = CurrentLiteral(); |
13877 ConsumeToken(); | 13257 ConsumeToken(); |
13878 } | 13258 } |
13879 // Resolve the type and optional identifier to a constructor or factory. | 13259 // Resolve the type and optional identifier to a constructor or factory. |
13880 Class& type_class = Class::Handle(Z, type.type_class()); | 13260 Class& type_class = Class::Handle(Z, type.type_class()); |
13881 String& type_class_name = String::Handle(Z, type_class.Name()); | 13261 String& type_class_name = String::Handle(Z, type_class.Name()); |
13882 *type_arguments = type.arguments(); | 13262 *type_arguments = type.arguments(); |
13883 String& constructor_name = BuildConstructorName(T, | 13263 String& constructor_name = |
13884 type_class_name, named_constructor); | 13264 BuildConstructorName(T, type_class_name, named_constructor); |
13885 *constructor = type_class.LookupConstructor(constructor_name); | 13265 *constructor = type_class.LookupConstructor(constructor_name); |
13886 if (constructor->IsNull()) { | 13266 if (constructor->IsNull()) { |
13887 *constructor = type_class.LookupFactory(constructor_name); | 13267 *constructor = type_class.LookupFactory(constructor_name); |
13888 ASSERT(!constructor->IsNull()); | 13268 ASSERT(!constructor->IsNull()); |
13889 if (constructor->IsRedirectingFactory()) { | 13269 if (constructor->IsRedirectingFactory()) { |
13890 ClassFinalizer::ResolveRedirectingFactory(type_class, *constructor); | 13270 ClassFinalizer::ResolveRedirectingFactory(type_class, *constructor); |
13891 type = constructor->RedirectionType(); | 13271 type = constructor->RedirectionType(); |
13892 ASSERT(!type.IsMalformedOrMalbounded()); | 13272 ASSERT(!type.IsMalformedOrMalbounded()); |
13893 if (!type.IsInstantiated()) { | 13273 if (!type.IsInstantiated()) { |
13894 Error& error = Error::Handle(Z); | 13274 Error& error = Error::Handle(Z); |
13895 type ^= type.InstantiateFrom(*type_arguments, | 13275 type ^= type.InstantiateFrom(*type_arguments, &error, |
13896 &error, | |
13897 NULL, // instantiation_trail | 13276 NULL, // instantiation_trail |
13898 NULL, // bound_trail | 13277 NULL, // bound_trail |
13899 Heap::kOld); | 13278 Heap::kOld); |
13900 ASSERT(error.IsNull()); | 13279 ASSERT(error.IsNull()); |
13901 } | 13280 } |
13902 *type_arguments = type.arguments(); | 13281 *type_arguments = type.arguments(); |
13903 *constructor = constructor->RedirectionTarget(); | 13282 *constructor = constructor->RedirectionTarget(); |
13904 } | 13283 } |
13905 } | 13284 } |
13906 } | 13285 } |
13907 | 13286 |
13908 | 13287 |
13909 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 13288 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
13910 TRACE_PARSER("ParseNewOperator"); | 13289 TRACE_PARSER("ParseNewOperator"); |
13911 const TokenPosition new_pos = TokenPos(); | 13290 const TokenPosition new_pos = TokenPos(); |
13912 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 13291 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
13913 bool is_const = (op_kind == Token::kCONST); | 13292 bool is_const = (op_kind == Token::kCONST); |
13914 if (!IsIdentifier()) { | 13293 if (!IsIdentifier()) { |
13915 ReportError("type name expected"); | 13294 ReportError("type name expected"); |
13916 } | 13295 } |
13917 TokenPosition type_pos = TokenPos(); | 13296 TokenPosition type_pos = TokenPos(); |
13918 // Can't allocate const objects of a deferred type. | 13297 // Can't allocate const objects of a deferred type. |
13919 const bool allow_deferred_type = !is_const; | 13298 const bool allow_deferred_type = !is_const; |
13920 const Token::Kind la3 = LookaheadToken(3); | 13299 const Token::Kind la3 = LookaheadToken(3); |
13921 const bool consume_unresolved_prefix = | 13300 const bool consume_unresolved_prefix = |
13922 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | 13301 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); |
13923 | 13302 |
13924 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 13303 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
13925 AbstractType& type = AbstractType::ZoneHandle(Z, | 13304 AbstractType& type = AbstractType::ZoneHandle( |
13926 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 13305 Z, ParseType(ClassFinalizer::kCanonicalizeWellFormed, allow_deferred_type, |
13927 allow_deferred_type, | 13306 consume_unresolved_prefix, &prefix)); |
13928 consume_unresolved_prefix, | |
13929 &prefix)); | |
13930 | 13307 |
13931 if (FLAG_load_deferred_eagerly && | 13308 if (FLAG_load_deferred_eagerly && !prefix.IsNull() && |
13932 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) { | 13309 prefix.is_deferred_load() && !prefix.is_loaded()) { |
13933 // Add runtime check. | 13310 // Add runtime check. |
13934 Type& malformed_type = Type::ZoneHandle(Z); | 13311 Type& malformed_type = Type::ZoneHandle(Z); |
13935 malformed_type = ClassFinalizer::NewFinalizedMalformedType( | 13312 malformed_type = ClassFinalizer::NewFinalizedMalformedType( |
13936 Error::Handle(Z), // No previous error. | 13313 Error::Handle(Z), // No previous error. |
13937 script_, | 13314 script_, type_pos, "deferred type '%s.%s' is not yet loaded", |
13938 type_pos, | |
13939 "deferred type '%s.%s' is not yet loaded", | |
13940 String::Handle(Z, prefix.name()).ToCString(), | 13315 String::Handle(Z, prefix.name()).ToCString(), |
13941 String::Handle(type.Name()).ToCString()); | 13316 String::Handle(type.Name()).ToCString()); |
13942 // Note: Adding a statement to current block is a hack, parsing an | 13317 // Note: Adding a statement to current block is a hack, parsing an |
13943 // expression should have no side-effect. | 13318 // expression should have no side-effect. |
13944 current_block_->statements->Add( | 13319 current_block_->statements->Add( |
13945 ThrowTypeError(type_pos, malformed_type, &prefix)); | 13320 ThrowTypeError(type_pos, malformed_type, &prefix)); |
13946 } | 13321 } |
13947 // In case the type is malformed, throw a dynamic type error after finishing | 13322 // In case the type is malformed, throw a dynamic type error after finishing |
13948 // parsing the instance creation expression. | 13323 // parsing the instance creation expression. |
13949 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 13324 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
13950 // Replace the type with a malformed type. | 13325 // Replace the type with a malformed type. |
13951 type = ClassFinalizer::NewFinalizedMalformedType( | 13326 type = ClassFinalizer::NewFinalizedMalformedType( |
13952 Error::Handle(Z), // No previous error. | 13327 Error::Handle(Z), // No previous error. |
13953 script_, | 13328 script_, type_pos, "%s'%s' cannot be instantiated", |
13954 type_pos, | |
13955 "%s'%s' cannot be instantiated", | |
13956 type.IsTypeParameter() ? "type parameter " : "", | 13329 type.IsTypeParameter() ? "type parameter " : "", |
13957 type.IsTypeParameter() ? | 13330 type.IsTypeParameter() |
13958 String::Handle(Z, type.UserVisibleName()).ToCString() : | 13331 ? String::Handle(Z, type.UserVisibleName()).ToCString() |
13959 "dynamic"); | 13332 : "dynamic"); |
13960 } | 13333 } |
13961 // Attempting to instantiate an enum type is a compile-time error. | 13334 // Attempting to instantiate an enum type is a compile-time error. |
13962 Class& type_class = Class::Handle(Z, type.type_class()); | 13335 Class& type_class = Class::Handle(Z, type.type_class()); |
13963 if (type_class.is_enum_class()) { | 13336 if (type_class.is_enum_class()) { |
13964 ReportError(new_pos, "enum type '%s' can not be instantiated", | 13337 ReportError(new_pos, "enum type '%s' can not be instantiated", |
13965 String::Handle(Z, type_class.Name()).ToCString()); | 13338 String::Handle(Z, type_class.Name()).ToCString()); |
13966 } | 13339 } |
13967 | 13340 |
13968 // The type can be followed by an optional named constructor identifier. | 13341 // The type can be followed by an optional named constructor identifier. |
13969 // Note that we tell ParseType() above not to consume it as part of | 13342 // Note that we tell ParseType() above not to consume it as part of |
(...skipping 17 matching lines...) Expand all Loading... |
13987 // Parse constructor parameters. | 13360 // Parse constructor parameters. |
13988 TokenPosition call_pos = TokenPos(); | 13361 TokenPosition call_pos = TokenPos(); |
13989 ArgumentListNode* arguments = NULL; | 13362 ArgumentListNode* arguments = NULL; |
13990 if (!is_tearoff_expression) { | 13363 if (!is_tearoff_expression) { |
13991 CheckToken(Token::kLPAREN); | 13364 CheckToken(Token::kLPAREN); |
13992 call_pos = TokenPos(); | 13365 call_pos = TokenPos(); |
13993 arguments = ParseActualParameters(NULL, is_const); | 13366 arguments = ParseActualParameters(NULL, is_const); |
13994 } else { | 13367 } else { |
13995 // Allocate dummy node with no arguments so we don't have to deal | 13368 // Allocate dummy node with no arguments so we don't have to deal |
13996 // with the NULL corner case below. | 13369 // with the NULL corner case below. |
13997 arguments = new(Z) ArgumentListNode(TokenPos()); | 13370 arguments = new (Z) ArgumentListNode(TokenPos()); |
13998 } | 13371 } |
13999 | 13372 |
14000 // Parsing is complete, so we can return a throw in case of a malformed or | 13373 // Parsing is complete, so we can return a throw in case of a malformed or |
14001 // malbounded type or report a compile-time error if the constructor is const. | 13374 // malbounded type or report a compile-time error if the constructor is const. |
14002 if (type.IsMalformedOrMalbounded()) { | 13375 if (type.IsMalformedOrMalbounded()) { |
14003 if (is_const) { | 13376 if (is_const) { |
14004 const Error& error = Error::Handle(Z, type.error()); | 13377 const Error& error = Error::Handle(Z, type.error()); |
14005 ReportError(error); | 13378 ReportError(error); |
14006 } | 13379 } |
14007 if (arguments->length() > 0) { | 13380 if (arguments->length() > 0) { |
14008 // Evaluate arguments for side-effects and throw. | 13381 // Evaluate arguments for side-effects and throw. |
14009 LetNode* error_result = new(Z) LetNode(type_pos); | 13382 LetNode* error_result = new (Z) LetNode(type_pos); |
14010 for (intptr_t i = 0; i < arguments->length(); ++i) { | 13383 for (intptr_t i = 0; i < arguments->length(); ++i) { |
14011 error_result->AddNode(arguments->NodeAt(i)); | 13384 error_result->AddNode(arguments->NodeAt(i)); |
14012 } | 13385 } |
14013 error_result->AddNode(ThrowTypeError(type_pos, type)); | 13386 error_result->AddNode(ThrowTypeError(type_pos, type)); |
14014 return error_result; | 13387 return error_result; |
14015 } | 13388 } |
14016 return ThrowTypeError(type_pos, type); | 13389 return ThrowTypeError(type_pos, type); |
14017 } | 13390 } |
14018 | 13391 |
14019 // Resolve the type and optional identifier to a constructor or factory. | 13392 // Resolve the type and optional identifier to a constructor or factory. |
14020 String& type_class_name = String::Handle(Z, type_class.Name()); | 13393 String& type_class_name = String::Handle(Z, type_class.Name()); |
14021 TypeArguments& type_arguments = | 13394 TypeArguments& type_arguments = |
14022 TypeArguments::ZoneHandle(Z, type.arguments()); | 13395 TypeArguments::ZoneHandle(Z, type.arguments()); |
14023 | 13396 |
14024 // A constructor has an implicit 'this' parameter (instance to construct) | 13397 // A constructor has an implicit 'this' parameter (instance to construct) |
14025 // and a factory has an implicit 'this' parameter (type_arguments). | 13398 // and a factory has an implicit 'this' parameter (type_arguments). |
14026 intptr_t arguments_length = arguments->length() + 1; | 13399 intptr_t arguments_length = arguments->length() + 1; |
14027 | 13400 |
14028 // An additional type check of the result of a redirecting factory may be | 13401 // An additional type check of the result of a redirecting factory may be |
14029 // required. | 13402 // required. |
14030 AbstractType& type_bound = AbstractType::ZoneHandle(Z); | 13403 AbstractType& type_bound = AbstractType::ZoneHandle(Z); |
14031 | 13404 |
14032 // Make sure that an appropriate constructor exists. | 13405 // Make sure that an appropriate constructor exists. |
14033 String& constructor_name = BuildConstructorName(T, | 13406 String& constructor_name = |
14034 type_class_name, named_constructor); | 13407 BuildConstructorName(T, type_class_name, named_constructor); |
14035 Function& constructor = Function::ZoneHandle(Z, | 13408 Function& constructor = |
14036 type_class.LookupConstructor(constructor_name)); | 13409 Function::ZoneHandle(Z, type_class.LookupConstructor(constructor_name)); |
14037 if (constructor.IsNull()) { | 13410 if (constructor.IsNull()) { |
14038 constructor = type_class.LookupFactory(constructor_name); | 13411 constructor = type_class.LookupFactory(constructor_name); |
14039 if (constructor.IsNull()) { | 13412 if (constructor.IsNull()) { |
14040 const String& external_constructor_name = | 13413 const String& external_constructor_name = |
14041 (named_constructor ? constructor_name : type_class_name); | 13414 (named_constructor ? constructor_name : type_class_name); |
14042 // Replace the type with a malformed type and compile a throw or report a | 13415 // Replace the type with a malformed type and compile a throw or report a |
14043 // compile-time error if the constructor is const. | 13416 // compile-time error if the constructor is const. |
14044 if (is_const) { | 13417 if (is_const) { |
14045 type = ClassFinalizer::NewFinalizedMalformedType( | 13418 type = ClassFinalizer::NewFinalizedMalformedType( |
14046 Error::Handle(Z), // No previous error. | 13419 Error::Handle(Z), // No previous error. |
14047 script_, | 13420 script_, call_pos, |
14048 call_pos, | |
14049 "class '%s' has no constructor or factory named '%s'", | 13421 "class '%s' has no constructor or factory named '%s'", |
14050 String::Handle(Z, type_class.Name()).ToCString(), | 13422 String::Handle(Z, type_class.Name()).ToCString(), |
14051 external_constructor_name.ToCString()); | 13423 external_constructor_name.ToCString()); |
14052 ReportError(Error::Handle(Z, type.error())); | 13424 ReportError(Error::Handle(Z, type.error())); |
14053 } | 13425 } |
14054 return ThrowNoSuchMethodError(call_pos, | 13426 return ThrowNoSuchMethodError( |
14055 type_class, | 13427 call_pos, type_class, external_constructor_name, arguments, |
14056 external_constructor_name, | 13428 InvocationMirror::kConstructor, InvocationMirror::kMethod, |
14057 arguments, | 13429 NULL); // No existing function. |
14058 InvocationMirror::kConstructor, | |
14059 InvocationMirror::kMethod, | |
14060 NULL); // No existing function. | |
14061 } else if (constructor.IsRedirectingFactory()) { | 13430 } else if (constructor.IsRedirectingFactory()) { |
14062 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); | 13431 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); |
14063 Type& redirect_type = Type::ZoneHandle(Z, constructor.RedirectionType()); | 13432 Type& redirect_type = Type::ZoneHandle(Z, constructor.RedirectionType()); |
14064 if (!redirect_type.IsMalformedOrMalbounded() && | 13433 if (!redirect_type.IsMalformedOrMalbounded() && |
14065 !redirect_type.IsInstantiated()) { | 13434 !redirect_type.IsInstantiated()) { |
14066 // The type arguments of the redirection type are instantiated from the | 13435 // The type arguments of the redirection type are instantiated from the |
14067 // type arguments of the parsed type of the 'new' or 'const' expression. | 13436 // type arguments of the parsed type of the 'new' or 'const' expression. |
14068 Error& error = Error::Handle(Z); | 13437 Error& error = Error::Handle(Z); |
14069 redirect_type ^= redirect_type.InstantiateFrom( | 13438 redirect_type ^= |
14070 type_arguments, | 13439 redirect_type.InstantiateFrom(type_arguments, &error, |
14071 &error, | 13440 NULL, // instantiation_trail |
14072 NULL, // instantiation_trail | 13441 NULL, // bound_trail |
14073 NULL, // bound_trail | 13442 Heap::kOld); |
14074 Heap::kOld); | |
14075 if (!error.IsNull()) { | 13443 if (!error.IsNull()) { |
14076 redirect_type = ClassFinalizer::NewFinalizedMalformedType( | 13444 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
14077 error, | 13445 error, script_, call_pos, |
14078 script_, | |
14079 call_pos, | |
14080 "redirecting factory type '%s' cannot be instantiated", | 13446 "redirecting factory type '%s' cannot be instantiated", |
14081 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); | 13447 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
14082 } | 13448 } |
14083 } | 13449 } |
14084 if (!redirect_type.HasResolvedTypeClass()) { | 13450 if (!redirect_type.HasResolvedTypeClass()) { |
14085 // If the redirection type is unresolved, we convert the allocation | 13451 // If the redirection type is unresolved, we convert the allocation |
14086 // into throwing a type error. | 13452 // into throwing a type error. |
14087 const UnresolvedClass& cls = | 13453 const UnresolvedClass& cls = |
14088 UnresolvedClass::Handle(Z, redirect_type.unresolved_class()); | 13454 UnresolvedClass::Handle(Z, redirect_type.unresolved_class()); |
14089 const LibraryPrefix& prefix = | 13455 const LibraryPrefix& prefix = |
14090 LibraryPrefix::Handle(Z, cls.library_prefix()); | 13456 LibraryPrefix::Handle(Z, cls.library_prefix()); |
14091 if (!prefix.IsNull() && !prefix.is_loaded() && | 13457 if (!prefix.IsNull() && !prefix.is_loaded() && |
14092 !FLAG_load_deferred_eagerly) { | 13458 !FLAG_load_deferred_eagerly) { |
14093 // If the redirection type is unresolved because it refers to | 13459 // If the redirection type is unresolved because it refers to |
14094 // an unloaded deferred prefix, mark this function as depending | 13460 // an unloaded deferred prefix, mark this function as depending |
14095 // on the library prefix. It will then get invalidated when the | 13461 // on the library prefix. It will then get invalidated when the |
14096 // prefix is loaded. | 13462 // prefix is loaded. |
14097 parsed_function()->AddDeferredPrefix(prefix); | 13463 parsed_function()->AddDeferredPrefix(prefix); |
14098 } | 13464 } |
14099 redirect_type = ClassFinalizer::NewFinalizedMalformedType( | 13465 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
14100 Error::Handle(Z), | 13466 Error::Handle(Z), script_, call_pos, |
14101 script_, | |
14102 call_pos, | |
14103 "redirection type '%s' is not loaded", | 13467 "redirection type '%s' is not loaded", |
14104 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); | 13468 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
14105 } | 13469 } |
14106 | 13470 |
14107 if (redirect_type.IsMalformedOrMalbounded()) { | 13471 if (redirect_type.IsMalformedOrMalbounded()) { |
14108 if (is_const) { | 13472 if (is_const) { |
14109 ReportError(Error::Handle(Z, redirect_type.error())); | 13473 ReportError(Error::Handle(Z, redirect_type.error())); |
14110 } | 13474 } |
14111 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 13475 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
14112 } | 13476 } |
14113 if (I->type_checks() && | 13477 if (I->type_checks() && |
14114 !redirect_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { | 13478 !redirect_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { |
14115 // Additional type checking of the result is necessary. | 13479 // Additional type checking of the result is necessary. |
14116 type_bound = type.raw(); | 13480 type_bound = type.raw(); |
14117 } | 13481 } |
14118 type = redirect_type.raw(); | 13482 type = redirect_type.raw(); |
14119 type_class = type.type_class(); | 13483 type_class = type.type_class(); |
14120 type_class_name = type_class.Name(); | 13484 type_class_name = type_class.Name(); |
14121 type_arguments = type.arguments(); | 13485 type_arguments = type.arguments(); |
14122 constructor = constructor.RedirectionTarget(); | 13486 constructor = constructor.RedirectionTarget(); |
14123 constructor_name = constructor.name(); | 13487 constructor_name = constructor.name(); |
14124 ASSERT(!constructor.IsNull()); | 13488 ASSERT(!constructor.IsNull()); |
14125 } | 13489 } |
14126 } | 13490 } |
14127 ASSERT(!constructor.IsNull()); | 13491 ASSERT(!constructor.IsNull()); |
14128 | 13492 |
14129 // It is a compile time error to instantiate a const instance of an | 13493 // It is a compile time error to instantiate a const instance of an |
14130 // abstract class. Factory methods are ok. | 13494 // abstract class. Factory methods are ok. |
14131 if (is_const && type_class.is_abstract() && !constructor.IsFactory()) { | 13495 if (is_const && type_class.is_abstract() && !constructor.IsFactory()) { |
14132 ReportError(new_pos, "cannot instantiate abstract class"); | 13496 ReportError(new_pos, "cannot instantiate abstract class"); |
14133 } | 13497 } |
14134 | 13498 |
14135 // It is ok to call a factory method of an abstract class, but it is | 13499 // It is ok to call a factory method of an abstract class, but it is |
14136 // a dynamic error to instantiate an abstract class. | 13500 // a dynamic error to instantiate an abstract class. |
14137 if (type_class.is_abstract() && !constructor.IsFactory()) { | 13501 if (type_class.is_abstract() && !constructor.IsFactory()) { |
14138 // Evaluate arguments before throwing. | 13502 // Evaluate arguments before throwing. |
14139 LetNode* result = new(Z) LetNode(call_pos); | 13503 LetNode* result = new (Z) LetNode(call_pos); |
14140 for (intptr_t i = 0; i < arguments->length(); ++i) { | 13504 for (intptr_t i = 0; i < arguments->length(); ++i) { |
14141 result->AddNode(arguments->NodeAt(i)); | 13505 result->AddNode(arguments->NodeAt(i)); |
14142 } | 13506 } |
14143 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); | 13507 ArgumentListNode* error_arguments = new (Z) ArgumentListNode(type_pos); |
14144 error_arguments->Add(new(Z) LiteralNode( | 13508 error_arguments->Add(new (Z) LiteralNode( |
14145 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos.value(), | 13509 TokenPos(), |
14146 Heap::kOld)))); | 13510 Integer::ZoneHandle(Z, Integer::New(type_pos.value(), Heap::kOld)))); |
14147 error_arguments->Add(new(Z) LiteralNode( | 13511 error_arguments->Add(new (Z) LiteralNode( |
14148 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); | 13512 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); |
14149 result->AddNode( | 13513 result->AddNode(MakeStaticCall( |
14150 MakeStaticCall(Symbols::AbstractClassInstantiationError(), | 13514 Symbols::AbstractClassInstantiationError(), |
14151 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 13515 Library::PrivateCoreLibName(Symbols::ThrowNew()), error_arguments)); |
14152 error_arguments)); | |
14153 return result; | 13516 return result; |
14154 } | 13517 } |
14155 | 13518 |
14156 type_arguments ^= type_arguments.Canonicalize(); | 13519 type_arguments ^= type_arguments.Canonicalize(); |
14157 | 13520 |
14158 if (is_tearoff_expression) { | 13521 if (is_tearoff_expression) { |
14159 const Function& tearoff_func = Function::ZoneHandle(Z, | 13522 const Function& tearoff_func = Function::ZoneHandle( |
14160 BuildConstructorClosureFunction(constructor, new_pos)); | 13523 Z, BuildConstructorClosureFunction(constructor, new_pos)); |
14161 | 13524 |
14162 // Local functions normally get parsed when the enclosing function is | 13525 // Local functions normally get parsed when the enclosing function is |
14163 // compiled. Since constructor tearoff closures don't get parsed here, | 13526 // compiled. Since constructor tearoff closures don't get parsed here, |
14164 // we need to duplicate some of the side effects of parsing, namely | 13527 // we need to duplicate some of the side effects of parsing, namely |
14165 // creating a function scope, and capturing the instantiator of the | 13528 // creating a function scope, and capturing the instantiator of the |
14166 // enclosing function if necessary. | 13529 // enclosing function if necessary. |
14167 OpenFunctionBlock(tearoff_func); | 13530 OpenFunctionBlock(tearoff_func); |
14168 // If there are type arguments in the tearoff expression that are | 13531 // If there are type arguments in the tearoff expression that are |
14169 // not yet instantiated, capture the instantiator. | 13532 // not yet instantiated, capture the instantiator. |
14170 if (IsInstantiatorRequired() && | 13533 if (IsInstantiatorRequired() && !type_arguments.IsNull() && |
14171 !type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 13534 !type_arguments.IsInstantiated()) { |
14172 CaptureInstantiator(); | 13535 CaptureInstantiator(); |
14173 } | 13536 } |
14174 SequenceNode* tearoff_body = CloseBlock(); | 13537 SequenceNode* tearoff_body = CloseBlock(); |
14175 ClosureNode* closure_obj = | 13538 ClosureNode* closure_obj = |
14176 new(Z) ClosureNode(new_pos, tearoff_func, NULL, tearoff_body->scope()); | 13539 new (Z) ClosureNode(new_pos, tearoff_func, NULL, tearoff_body->scope()); |
14177 return closure_obj; | 13540 return closure_obj; |
14178 } | 13541 } |
14179 | 13542 |
14180 ASSERT(!is_tearoff_expression); | 13543 ASSERT(!is_tearoff_expression); |
14181 String& error_message = String::Handle(Z); | 13544 String& error_message = String::Handle(Z); |
14182 if (!constructor.AreValidArguments(arguments_length, | 13545 if (!constructor.AreValidArguments(arguments_length, arguments->names(), |
14183 arguments->names(), | |
14184 &error_message)) { | 13546 &error_message)) { |
14185 const String& external_constructor_name = | 13547 const String& external_constructor_name = |
14186 (named_constructor ? constructor_name : type_class_name); | 13548 (named_constructor ? constructor_name : type_class_name); |
14187 if (is_const) { | 13549 if (is_const) { |
14188 ReportError(call_pos, | 13550 ReportError(call_pos, |
14189 "invalid arguments passed to constructor '%s' " | 13551 "invalid arguments passed to constructor '%s' " |
14190 "for class '%s': %s", | 13552 "for class '%s': %s", |
14191 external_constructor_name.ToCString(), | 13553 external_constructor_name.ToCString(), |
14192 String::Handle(Z, type_class.Name()).ToCString(), | 13554 String::Handle(Z, type_class.Name()).ToCString(), |
14193 error_message.ToCString()); | 13555 error_message.ToCString()); |
14194 } | 13556 } |
14195 return ThrowNoSuchMethodError(call_pos, | 13557 return ThrowNoSuchMethodError(call_pos, type_class, |
14196 type_class, | 13558 external_constructor_name, arguments, |
14197 external_constructor_name, | |
14198 arguments, | |
14199 InvocationMirror::kConstructor, | 13559 InvocationMirror::kConstructor, |
14200 InvocationMirror::kMethod, | 13560 InvocationMirror::kMethod, &constructor); |
14201 &constructor); | |
14202 } | 13561 } |
14203 | 13562 |
14204 // Return a throw in case of a malformed or malbounded type or report a | 13563 // Return a throw in case of a malformed or malbounded type or report a |
14205 // compile-time error if the constructor is const. | 13564 // compile-time error if the constructor is const. |
14206 if (type.IsMalformedOrMalbounded()) { | 13565 if (type.IsMalformedOrMalbounded()) { |
14207 if (is_const) { | 13566 if (is_const) { |
14208 ReportError(Error::Handle(Z, type.error())); | 13567 ReportError(Error::Handle(Z, type.error())); |
14209 } | 13568 } |
14210 return ThrowTypeError(type_pos, type); | 13569 return ThrowTypeError(type_pos, type); |
14211 } | 13570 } |
14212 | 13571 |
14213 // Make the constructor call. | 13572 // Make the constructor call. |
14214 AstNode* new_object = NULL; | 13573 AstNode* new_object = NULL; |
14215 if (is_const) { | 13574 if (is_const) { |
14216 if (!constructor.is_const()) { | 13575 if (!constructor.is_const()) { |
14217 const String& external_constructor_name = | 13576 const String& external_constructor_name = |
14218 (named_constructor ? constructor_name : type_class_name); | 13577 (named_constructor ? constructor_name : type_class_name); |
14219 ReportError("non-const constructor '%s' cannot be used in " | 13578 ReportError( |
14220 "const object creation", | 13579 "non-const constructor '%s' cannot be used in " |
14221 external_constructor_name.ToCString()); | 13580 "const object creation", |
| 13581 external_constructor_name.ToCString()); |
14222 } | 13582 } |
14223 | 13583 |
14224 Instance& const_instance = Instance::ZoneHandle(Z); | 13584 Instance& const_instance = Instance::ZoneHandle(Z); |
14225 if (GetCachedConstant(new_pos, &const_instance)) { | 13585 if (GetCachedConstant(new_pos, &const_instance)) { |
14226 // Cache hit, nothing else to do. | 13586 // Cache hit, nothing else to do. |
14227 } else { | 13587 } else { |
14228 Object& constructor_result = Object::Handle(Z, | 13588 Object& constructor_result = Object::Handle( |
14229 EvaluateConstConstructorCall(type_class, | 13589 Z, EvaluateConstConstructorCall(type_class, type_arguments, |
14230 type_arguments, | 13590 constructor, arguments)); |
14231 constructor, | |
14232 arguments)); | |
14233 if (constructor_result.IsUnhandledException()) { | 13591 if (constructor_result.IsUnhandledException()) { |
14234 // It's a compile-time error if invocation of a const constructor | 13592 // It's a compile-time error if invocation of a const constructor |
14235 // call fails. | 13593 // call fails. |
14236 ReportErrors(Error::Cast(constructor_result), | 13594 ReportErrors(Error::Cast(constructor_result), script_, new_pos, |
14237 script_, new_pos, | |
14238 "error while evaluating const constructor"); | 13595 "error while evaluating const constructor"); |
14239 } | 13596 } |
14240 const_instance ^= constructor_result.raw(); | 13597 const_instance ^= constructor_result.raw(); |
14241 CacheConstantValue(new_pos, const_instance); | 13598 CacheConstantValue(new_pos, const_instance); |
14242 } | 13599 } |
14243 new_object = new(Z) LiteralNode(new_pos, const_instance); | 13600 new_object = new (Z) LiteralNode(new_pos, const_instance); |
14244 if (!type_bound.IsNull()) { | 13601 if (!type_bound.IsNull()) { |
14245 ASSERT(!type_bound.IsMalformed()); | 13602 ASSERT(!type_bound.IsMalformed()); |
14246 Error& bound_error = Error::Handle(Z); | 13603 Error& bound_error = Error::Handle(Z); |
14247 ASSERT(!is_top_level_); // We cannot check unresolved types. | 13604 ASSERT(!is_top_level_); // We cannot check unresolved types. |
14248 if (!const_instance.IsInstanceOf(type_bound, | 13605 if (!const_instance.IsInstanceOf(type_bound, TypeArguments::Handle(Z), |
14249 TypeArguments::Handle(Z), | |
14250 &bound_error)) { | 13606 &bound_error)) { |
14251 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 13607 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
14252 bound_error, | 13608 bound_error, script_, new_pos, |
14253 script_, | |
14254 new_pos, | |
14255 "const factory result is not an instance of '%s'", | 13609 "const factory result is not an instance of '%s'", |
14256 String::Handle(Z, type_bound.UserVisibleName()).ToCString()); | 13610 String::Handle(Z, type_bound.UserVisibleName()).ToCString()); |
14257 new_object = ThrowTypeError(new_pos, type_bound); | 13611 new_object = ThrowTypeError(new_pos, type_bound); |
14258 } | 13612 } |
14259 type_bound = AbstractType::null(); | 13613 type_bound = AbstractType::null(); |
14260 } | 13614 } |
14261 } else { | 13615 } else { |
14262 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 13616 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
14263 if (!type_arguments.IsNull() && | 13617 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated() && |
14264 !type_arguments.IsInstantiated() && | |
14265 (FunctionLevel() > 0)) { | 13618 (FunctionLevel() > 0)) { |
14266 // Make sure that the instantiator is captured. | 13619 // Make sure that the instantiator is captured. |
14267 CaptureInstantiator(); | 13620 CaptureInstantiator(); |
14268 } | 13621 } |
14269 // If the type argument vector is not instantiated, we verify in checked | 13622 // If the type argument vector is not instantiated, we verify in checked |
14270 // mode at runtime that it is within its declared bounds. | 13623 // mode at runtime that it is within its declared bounds. |
14271 new_object = CreateConstructorCallNode( | 13624 new_object = CreateConstructorCallNode(new_pos, type_arguments, constructor, |
14272 new_pos, type_arguments, constructor, arguments); | 13625 arguments); |
14273 } | 13626 } |
14274 if (!type_bound.IsNull()) { | 13627 if (!type_bound.IsNull()) { |
14275 new_object = new(Z) AssignableNode( | 13628 new_object = new (Z) AssignableNode(new_pos, new_object, type_bound, |
14276 new_pos, new_object, type_bound, Symbols::FactoryResult()); | 13629 Symbols::FactoryResult()); |
14277 } | 13630 } |
14278 return new_object; | 13631 return new_object; |
14279 } | 13632 } |
14280 | 13633 |
14281 | 13634 |
14282 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { | 13635 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { |
14283 NoReloadScope no_reload_scope(isolate(), thread()); | 13636 NoReloadScope no_reload_scope(isolate(), thread()); |
14284 NoOOBMessageScope no_msg_scope(thread()); | 13637 NoOOBMessageScope no_msg_scope(thread()); |
14285 const Class& cls = Class::Handle( | 13638 const Class& cls = |
14286 Z, Library::LookupCoreClass(Symbols::StringBase())); | 13639 Class::Handle(Z, Library::LookupCoreClass(Symbols::StringBase())); |
14287 ASSERT(!cls.IsNull()); | 13640 ASSERT(!cls.IsNull()); |
14288 const Function& func = Function::Handle(Z, cls.LookupStaticFunction( | 13641 const Function& func = Function::Handle( |
14289 Library::PrivateCoreLibName(Symbols::Interpolate()))); | 13642 Z, cls.LookupStaticFunction( |
| 13643 Library::PrivateCoreLibName(Symbols::Interpolate()))); |
14290 ASSERT(!func.IsNull()); | 13644 ASSERT(!func.IsNull()); |
14291 | 13645 |
14292 // Build the array of literal values to interpolate. | 13646 // Build the array of literal values to interpolate. |
14293 const Array& value_arr = Array::Handle(Z, | 13647 const Array& value_arr = |
14294 Array::New(values.length(), Heap::kOld)); | 13648 Array::Handle(Z, Array::New(values.length(), Heap::kOld)); |
14295 for (int i = 0; i < values.length(); i++) { | 13649 for (int i = 0; i < values.length(); i++) { |
14296 ASSERT(values[i]->IsLiteralNode()); | 13650 ASSERT(values[i]->IsLiteralNode()); |
14297 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); | 13651 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); |
14298 } | 13652 } |
14299 | 13653 |
14300 // Build argument array to pass to the interpolation function. | 13654 // Build argument array to pass to the interpolation function. |
14301 const Array& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld)); | 13655 const Array& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld)); |
14302 interpolate_arg.SetAt(0, value_arr); | 13656 interpolate_arg.SetAt(0, value_arr); |
14303 | 13657 |
14304 // Call interpolation function. | 13658 // Call interpolation function. |
(...skipping 14 matching lines...) Expand all Loading... |
14319 // literal = kSTRING {{ interpol } kSTRING } | 13673 // literal = kSTRING {{ interpol } kSTRING } |
14320 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 13674 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
14321 // In other words, the scanner breaks down interpolated strings so that | 13675 // In other words, the scanner breaks down interpolated strings so that |
14322 // a string literal always begins and ends with a kSTRING token. | 13676 // a string literal always begins and ends with a kSTRING token. |
14323 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 13677 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
14324 TRACE_PARSER("ParseStringLiteral"); | 13678 TRACE_PARSER("ParseStringLiteral"); |
14325 AstNode* primary = NULL; | 13679 AstNode* primary = NULL; |
14326 const TokenPosition literal_start = TokenPos(); | 13680 const TokenPosition literal_start = TokenPos(); |
14327 ASSERT(CurrentToken() == Token::kSTRING); | 13681 ASSERT(CurrentToken() == Token::kSTRING); |
14328 Token::Kind l1_token = LookaheadToken(1); | 13682 Token::Kind l1_token = LookaheadToken(1); |
14329 if ((l1_token != Token::kSTRING) && | 13683 if ((l1_token != Token::kSTRING) && (l1_token != Token::kINTERPOL_VAR) && |
14330 (l1_token != Token::kINTERPOL_VAR) && | |
14331 (l1_token != Token::kINTERPOL_START)) { | 13684 (l1_token != Token::kINTERPOL_START)) { |
14332 // Common case: no interpolation. | 13685 // Common case: no interpolation. |
14333 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); | 13686 primary = new (Z) LiteralNode(literal_start, *CurrentLiteral()); |
14334 ConsumeToken(); | 13687 ConsumeToken(); |
14335 return primary; | 13688 return primary; |
14336 } | 13689 } |
14337 // String interpolation needed. | 13690 // String interpolation needed. |
14338 | 13691 |
14339 // First, check whether we've cached a compile-time constant for this | 13692 // First, check whether we've cached a compile-time constant for this |
14340 // string interpolation. | 13693 // string interpolation. |
14341 Instance& cached_string = Instance::Handle(Z); | 13694 Instance& cached_string = Instance::Handle(Z); |
14342 if (GetCachedConstant(literal_start, &cached_string)) { | 13695 if (GetCachedConstant(literal_start, &cached_string)) { |
14343 SkipStringLiteral(); | 13696 SkipStringLiteral(); |
14344 return new(Z) LiteralNode(literal_start, | 13697 return new (Z) LiteralNode(literal_start, |
14345 Instance::ZoneHandle(Z, cached_string.raw())); | 13698 Instance::ZoneHandle(Z, cached_string.raw())); |
14346 } | 13699 } |
14347 | 13700 |
14348 bool is_compiletime_const = true; | 13701 bool is_compiletime_const = true; |
14349 bool has_interpolation = false; | 13702 bool has_interpolation = false; |
14350 GrowableArray<AstNode*> values_list; | 13703 GrowableArray<AstNode*> values_list; |
14351 while (CurrentToken() == Token::kSTRING) { | 13704 while (CurrentToken() == Token::kSTRING) { |
14352 if (CurrentLiteral()->Length() > 0) { | 13705 if (CurrentLiteral()->Length() > 0) { |
14353 // Only add non-empty string sections to the values list | 13706 // Only add non-empty string sections to the values list |
14354 // that will be concatenated. | 13707 // that will be concatenated. |
14355 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); | 13708 values_list.Add(new (Z) LiteralNode(TokenPos(), *CurrentLiteral())); |
14356 } | 13709 } |
14357 ConsumeToken(); | 13710 ConsumeToken(); |
14358 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 13711 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
14359 (CurrentToken() == Token::kINTERPOL_START)) { | 13712 (CurrentToken() == Token::kINTERPOL_START)) { |
14360 if (!allow_interpolation) { | 13713 if (!allow_interpolation) { |
14361 ReportError("string interpolation not allowed in this context"); | 13714 ReportError("string interpolation not allowed in this context"); |
14362 } | 13715 } |
14363 has_interpolation = true; | 13716 has_interpolation = true; |
14364 AstNode* expr = NULL; | 13717 AstNode* expr = NULL; |
14365 const TokenPosition expr_pos = TokenPos(); | 13718 const TokenPosition expr_pos = TokenPos(); |
14366 if (CurrentToken() == Token::kINTERPOL_VAR) { | 13719 if (CurrentToken() == Token::kINTERPOL_VAR) { |
14367 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); | 13720 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); |
14368 ConsumeToken(); | 13721 ConsumeToken(); |
14369 } else { | 13722 } else { |
14370 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 13723 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
14371 ConsumeToken(); | 13724 ConsumeToken(); |
14372 const bool saved_mode = SetAllowFunctionLiterals(true); | 13725 const bool saved_mode = SetAllowFunctionLiterals(true); |
14373 expr = ParseExpr(kAllowConst, kConsumeCascades); | 13726 expr = ParseExpr(kAllowConst, kConsumeCascades); |
14374 SetAllowFunctionLiterals(saved_mode); | 13727 SetAllowFunctionLiterals(saved_mode); |
14375 ExpectToken(Token::kINTERPOL_END); | 13728 ExpectToken(Token::kINTERPOL_END); |
14376 } | 13729 } |
14377 // Check if this interpolated string is still considered a compile time | 13730 // Check if this interpolated string is still considered a compile time |
14378 // constant. If it is we need to evaluate if the current string part is | 13731 // constant. If it is we need to evaluate if the current string part is |
14379 // a constant or not. Only strings, numbers, booleans and null values | 13732 // a constant or not. Only strings, numbers, booleans and null values |
14380 // are allowed in compile time const interpolations. | 13733 // are allowed in compile time const interpolations. |
14381 if (is_compiletime_const) { | 13734 if (is_compiletime_const) { |
14382 const Object* const_expr = expr->EvalConstExpr(); | 13735 const Object* const_expr = expr->EvalConstExpr(); |
14383 if ((const_expr != NULL) && | 13736 if ((const_expr != NULL) && |
14384 (const_expr->IsNumber() || | 13737 (const_expr->IsNumber() || const_expr->IsString() || |
14385 const_expr->IsString() || | 13738 const_expr->IsBool() || const_expr->IsNull())) { |
14386 const_expr->IsBool() || | |
14387 const_expr->IsNull())) { | |
14388 // Change expr into a literal. | 13739 // Change expr into a literal. |
14389 expr = new(Z) LiteralNode(expr_pos, | 13740 expr = |
14390 EvaluateConstExpr(expr_pos, expr)); | 13741 new (Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr)); |
14391 } else { | 13742 } else { |
14392 is_compiletime_const = false; | 13743 is_compiletime_const = false; |
14393 } | 13744 } |
14394 } | 13745 } |
14395 values_list.Add(expr); | 13746 values_list.Add(expr); |
14396 } | 13747 } |
14397 } | 13748 } |
14398 if (is_compiletime_const) { | 13749 if (is_compiletime_const) { |
14399 if (has_interpolation) { | 13750 if (has_interpolation) { |
14400 const String& interpolated_string = Interpolate(values_list); | 13751 const String& interpolated_string = Interpolate(values_list); |
14401 primary = new(Z) LiteralNode(literal_start, interpolated_string); | 13752 primary = new (Z) LiteralNode(literal_start, interpolated_string); |
14402 CacheConstantValue(literal_start, interpolated_string); | 13753 CacheConstantValue(literal_start, interpolated_string); |
14403 } else { | 13754 } else { |
14404 GrowableHandlePtrArray<const String> pieces(Z, values_list.length()); | 13755 GrowableHandlePtrArray<const String> pieces(Z, values_list.length()); |
14405 for (int i = 0; i < values_list.length(); i++) { | 13756 for (int i = 0; i < values_list.length(); i++) { |
14406 const Instance& part = values_list[i]->AsLiteralNode()->literal(); | 13757 const Instance& part = values_list[i]->AsLiteralNode()->literal(); |
14407 ASSERT(part.IsString()); | 13758 ASSERT(part.IsString()); |
14408 pieces.Add(String::Cast(part)); | 13759 pieces.Add(String::Cast(part)); |
14409 } | 13760 } |
14410 const String& lit = String::ZoneHandle(Z, | 13761 const String& lit = |
14411 Symbols::FromConcatAll(T, pieces)); | 13762 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); |
14412 primary = new(Z) LiteralNode(literal_start, lit); | 13763 primary = new (Z) LiteralNode(literal_start, lit); |
14413 // Caching of constant not necessary because the symbol lookup will | 13764 // Caching of constant not necessary because the symbol lookup will |
14414 // find the value next time. | 13765 // find the value next time. |
14415 } | 13766 } |
14416 } else { | 13767 } else { |
14417 ArrayNode* values = new(Z) ArrayNode( | 13768 ArrayNode* values = new (Z) ArrayNode( |
14418 TokenPos(), | 13769 TokenPos(), Type::ZoneHandle(Z, Type::ArrayType()), values_list); |
14419 Type::ZoneHandle(Z, Type::ArrayType()), | 13770 primary = new (Z) StringInterpolateNode(TokenPos(), values); |
14420 values_list); | |
14421 primary = new(Z) StringInterpolateNode(TokenPos(), values); | |
14422 } | 13771 } |
14423 return primary; | 13772 return primary; |
14424 } | 13773 } |
14425 | 13774 |
14426 | 13775 |
14427 AstNode* Parser::ParsePrimary() { | 13776 AstNode* Parser::ParsePrimary() { |
14428 TRACE_PARSER("ParsePrimary"); | 13777 TRACE_PARSER("ParsePrimary"); |
14429 ASSERT(!is_top_level_); | 13778 ASSERT(!is_top_level_); |
14430 AstNode* primary = NULL; | 13779 AstNode* primary = NULL; |
14431 const Token::Kind token = CurrentToken(); | 13780 const Token::Kind token = CurrentToken(); |
14432 if (IsFunctionLiteral()) { | 13781 if (IsFunctionLiteral()) { |
14433 // The name of a literal function is visible from inside the function, but | 13782 // The name of a literal function is visible from inside the function, but |
14434 // must not collide with names in the scope declaring the literal. | 13783 // must not collide with names in the scope declaring the literal. |
14435 OpenBlock(); | 13784 OpenBlock(); |
14436 primary = ParseFunctionStatement(true); | 13785 primary = ParseFunctionStatement(true); |
14437 CloseBlock(); | 13786 CloseBlock(); |
14438 } else if (IsIdentifier()) { | 13787 } else if (IsIdentifier()) { |
14439 TokenPosition qual_ident_pos = TokenPos(); | 13788 TokenPosition qual_ident_pos = TokenPos(); |
14440 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13789 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
14441 if (!prefix.IsNull()) { | 13790 if (!prefix.IsNull()) { |
14442 if (CurrentToken() == Token::kHASH) { | 13791 if (CurrentToken() == Token::kHASH) { |
14443 // Closurization of top-level entity in prefix scope. | 13792 // Closurization of top-level entity in prefix scope. |
14444 return new(Z) LiteralNode(qual_ident_pos, prefix); | 13793 return new (Z) LiteralNode(qual_ident_pos, prefix); |
14445 } else { | 13794 } else { |
14446 ExpectToken(Token::kPERIOD); | 13795 ExpectToken(Token::kPERIOD); |
14447 } | 13796 } |
14448 } | 13797 } |
14449 String& ident = *CurrentLiteral(); | 13798 String& ident = *CurrentLiteral(); |
14450 ConsumeToken(); | 13799 ConsumeToken(); |
14451 if (prefix.IsNull()) { | 13800 if (prefix.IsNull()) { |
14452 intptr_t primary_func_level = 0; | 13801 intptr_t primary_func_level = 0; |
14453 ResolveIdentInLocalScope( | 13802 ResolveIdentInLocalScope(qual_ident_pos, ident, &primary, |
14454 qual_ident_pos, ident, &primary, &primary_func_level); | 13803 &primary_func_level); |
14455 // Check whether the identifier is shadowed by a function type parameter. | 13804 // Check whether the identifier is shadowed by a function type parameter. |
14456 if (!innermost_function().IsNull()) { | 13805 if (!innermost_function().IsNull()) { |
14457 // TODO(regis): Shortcut this lookup if no generic functions in scope. | 13806 // TODO(regis): Shortcut this lookup if no generic functions in scope. |
14458 intptr_t type_param_func_level = FunctionLevel(); | 13807 intptr_t type_param_func_level = FunctionLevel(); |
14459 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, | 13808 TypeParameter& type_param = TypeParameter::ZoneHandle( |
14460 innermost_function().LookupTypeParameter(ident, | 13809 Z, innermost_function().LookupTypeParameter( |
14461 &type_param_func_level)); | 13810 ident, &type_param_func_level)); |
14462 if (!type_param.IsNull()) { | 13811 if (!type_param.IsNull()) { |
14463 if ((primary == NULL) || | 13812 if ((primary == NULL) || |
14464 (primary_func_level < type_param_func_level)) { | 13813 (primary_func_level < type_param_func_level)) { |
14465 // The identifier is a function type parameter, possibly shadowing | 13814 // The identifier is a function type parameter, possibly shadowing |
14466 // already resolved 'primary'. | 13815 // already resolved 'primary'. |
14467 if (type_param_func_level < FunctionLevel()) { | 13816 if (type_param_func_level < FunctionLevel()) { |
14468 // Make sure that the function instantiator is captured. | 13817 // Make sure that the function instantiator is captured. |
14469 CaptureFunctionInstantiator(); | 13818 CaptureFunctionInstantiator(); |
14470 } | 13819 } |
14471 return new(Z) PrimaryNode(qual_ident_pos, type_param); | 13820 return new (Z) PrimaryNode(qual_ident_pos, type_param); |
14472 } | 13821 } |
14473 } | 13822 } |
14474 } | 13823 } |
14475 if (primary == NULL) { | 13824 if (primary == NULL) { |
14476 // Check whether the identifier is a type parameter. | 13825 // Check whether the identifier is a type parameter. |
14477 if (!current_class().IsNull()) { | 13826 if (!current_class().IsNull()) { |
14478 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, | 13827 TypeParameter& type_param = TypeParameter::ZoneHandle( |
14479 current_class().LookupTypeParameter(ident)); | 13828 Z, current_class().LookupTypeParameter(ident)); |
14480 if (!type_param.IsNull()) { | 13829 if (!type_param.IsNull()) { |
14481 return new(Z) PrimaryNode(qual_ident_pos, type_param); | 13830 return new (Z) PrimaryNode(qual_ident_pos, type_param); |
14482 } | 13831 } |
14483 } | 13832 } |
14484 // This is a non-local unqualified identifier so resolve the | 13833 // This is a non-local unqualified identifier so resolve the |
14485 // identifier locally in the main app library and all libraries | 13834 // identifier locally in the main app library and all libraries |
14486 // imported by it. | 13835 // imported by it. |
14487 primary = ResolveIdentInCurrentLibraryScope(qual_ident_pos, ident); | 13836 primary = ResolveIdentInCurrentLibraryScope(qual_ident_pos, ident); |
14488 } | 13837 } |
14489 } else { | 13838 } else { |
14490 // This is a qualified identifier with a library prefix so resolve | 13839 // This is a qualified identifier with a library prefix so resolve |
14491 // the identifier locally in that library (we do not include the | 13840 // the identifier locally in that library (we do not include the |
14492 // libraries imported by that library). | 13841 // libraries imported by that library). |
14493 primary = ResolveIdentInPrefixScope(qual_ident_pos, prefix, ident); | 13842 primary = ResolveIdentInPrefixScope(qual_ident_pos, prefix, ident); |
14494 | 13843 |
14495 // If the identifier could not be resolved, throw a NoSuchMethodError. | 13844 // If the identifier could not be resolved, throw a NoSuchMethodError. |
14496 // Note: unlike in the case of an unqualified identifier, do not | 13845 // Note: unlike in the case of an unqualified identifier, do not |
14497 // interpret the unresolved identifier as an instance method or | 13846 // interpret the unresolved identifier as an instance method or |
14498 // instance getter call when compiling an instance method. | 13847 // instance getter call when compiling an instance method. |
14499 if (primary == NULL) { | 13848 if (primary == NULL) { |
14500 if (prefix.is_deferred_load() && | 13849 if (prefix.is_deferred_load() && ident.Equals(Symbols::LoadLibrary())) { |
14501 ident.Equals(Symbols::LoadLibrary())) { | |
14502 // Hack Alert: recognize special 'loadLibrary' call on the | 13850 // Hack Alert: recognize special 'loadLibrary' call on the |
14503 // prefix object. The prefix is the primary. Rewind parser and | 13851 // prefix object. The prefix is the primary. Rewind parser and |
14504 // let ParseSelectors() handle the loadLibrary call. | 13852 // let ParseSelectors() handle the loadLibrary call. |
14505 SetPosition(qual_ident_pos); | 13853 SetPosition(qual_ident_pos); |
14506 ConsumeToken(); // Prefix name. | 13854 ConsumeToken(); // Prefix name. |
14507 primary = new(Z) LiteralNode(qual_ident_pos, prefix); | 13855 primary = new (Z) LiteralNode(qual_ident_pos, prefix); |
14508 } else { | 13856 } else { |
14509 GrowableHandlePtrArray<const String> pieces(Z, 3); | 13857 GrowableHandlePtrArray<const String> pieces(Z, 3); |
14510 pieces.Add(String::Handle(Z, prefix.name())); | 13858 pieces.Add(String::Handle(Z, prefix.name())); |
14511 pieces.Add(Symbols::Dot()); | 13859 pieces.Add(Symbols::Dot()); |
14512 pieces.Add(ident); | 13860 pieces.Add(ident); |
14513 const String& qualified_name = String::ZoneHandle(Z, | 13861 const String& qualified_name = |
14514 Symbols::FromConcatAll(T, pieces)); | 13862 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); |
14515 primary = new(Z) PrimaryNode(qual_ident_pos, qualified_name); | 13863 primary = new (Z) PrimaryNode(qual_ident_pos, qualified_name); |
14516 } | 13864 } |
14517 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) { | 13865 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) { |
14518 // primary != NULL. | 13866 // primary != NULL. |
14519 GrowableHandlePtrArray<const String> pieces(Z, 3); | 13867 GrowableHandlePtrArray<const String> pieces(Z, 3); |
14520 pieces.Add(String::Handle(Z, prefix.name())); | 13868 pieces.Add(String::Handle(Z, prefix.name())); |
14521 pieces.Add(Symbols::Dot()); | 13869 pieces.Add(Symbols::Dot()); |
14522 pieces.Add(ident); | 13870 pieces.Add(ident); |
14523 const String& qualified_name = String::ZoneHandle(Z, | 13871 const String& qualified_name = |
14524 Symbols::FromConcatAll(T, pieces)); | 13872 String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces)); |
14525 InvocationMirror::Type call_type = | 13873 InvocationMirror::Type call_type = CurrentToken() == Token::kLPAREN |
14526 CurrentToken() == Token::kLPAREN ? | 13874 ? InvocationMirror::kMethod |
14527 InvocationMirror::kMethod : InvocationMirror::kGetter; | 13875 : InvocationMirror::kGetter; |
14528 // Note: Adding a statement to current block is a hack, parsing an | 13876 // Note: Adding a statement to current block is a hack, parsing an |
14529 // espression should have no side-effect. | 13877 // espression should have no side-effect. |
14530 current_block_->statements->Add(ThrowNoSuchMethodError( | 13878 current_block_->statements->Add(ThrowNoSuchMethodError( |
14531 qual_ident_pos, | 13879 qual_ident_pos, current_class(), qualified_name, |
14532 current_class(), | 13880 NULL, // No arguments. |
14533 qualified_name, | 13881 InvocationMirror::kTopLevel, call_type, |
14534 NULL, // No arguments. | 13882 NULL, // No existing function. |
14535 InvocationMirror::kTopLevel, | 13883 &prefix)); |
14536 call_type, | |
14537 NULL, // No existing function. | |
14538 &prefix)); | |
14539 } | 13884 } |
14540 } | 13885 } |
14541 ASSERT(primary != NULL); | 13886 ASSERT(primary != NULL); |
14542 } else if (token == Token::kTHIS) { | 13887 } else if (token == Token::kTHIS) { |
14543 LocalVariable* local = LookupLocalScope(Symbols::This()); | 13888 LocalVariable* local = LookupLocalScope(Symbols::This()); |
14544 if (local == NULL) { | 13889 if (local == NULL) { |
14545 ReportError("receiver 'this' is not in scope"); | 13890 ReportError("receiver 'this' is not in scope"); |
14546 } | 13891 } |
14547 primary = new(Z) LoadLocalNode(TokenPos(), local); | 13892 primary = new (Z) LoadLocalNode(TokenPos(), local); |
14548 ConsumeToken(); | 13893 ConsumeToken(); |
14549 } else if (token == Token::kINTEGER) { | 13894 } else if (token == Token::kINTEGER) { |
14550 const Integer& literal = Integer::ZoneHandle(Z, CurrentIntegerLiteral()); | 13895 const Integer& literal = Integer::ZoneHandle(Z, CurrentIntegerLiteral()); |
14551 primary = new(Z) LiteralNode(TokenPos(), literal); | 13896 primary = new (Z) LiteralNode(TokenPos(), literal); |
14552 ConsumeToken(); | 13897 ConsumeToken(); |
14553 } else if (token == Token::kTRUE) { | 13898 } else if (token == Token::kTRUE) { |
14554 primary = new(Z) LiteralNode(TokenPos(), Bool::True()); | 13899 primary = new (Z) LiteralNode(TokenPos(), Bool::True()); |
14555 ConsumeToken(); | 13900 ConsumeToken(); |
14556 } else if (token == Token::kFALSE) { | 13901 } else if (token == Token::kFALSE) { |
14557 primary = new(Z) LiteralNode(TokenPos(), Bool::False()); | 13902 primary = new (Z) LiteralNode(TokenPos(), Bool::False()); |
14558 ConsumeToken(); | 13903 ConsumeToken(); |
14559 } else if (token == Token::kNULL) { | 13904 } else if (token == Token::kNULL) { |
14560 primary = new(Z) LiteralNode(TokenPos(), Object::null_instance()); | 13905 primary = new (Z) LiteralNode(TokenPos(), Object::null_instance()); |
14561 ConsumeToken(); | 13906 ConsumeToken(); |
14562 } else if (token == Token::kLPAREN) { | 13907 } else if (token == Token::kLPAREN) { |
14563 ConsumeToken(); | 13908 ConsumeToken(); |
14564 const bool saved_mode = SetAllowFunctionLiterals(true); | 13909 const bool saved_mode = SetAllowFunctionLiterals(true); |
14565 primary = ParseExpr(kAllowConst, kConsumeCascades); | 13910 primary = ParseExpr(kAllowConst, kConsumeCascades); |
14566 SetAllowFunctionLiterals(saved_mode); | 13911 SetAllowFunctionLiterals(saved_mode); |
14567 ExpectToken(Token::kRPAREN); | 13912 ExpectToken(Token::kRPAREN); |
14568 } else if (token == Token::kDOUBLE) { | 13913 } else if (token == Token::kDOUBLE) { |
14569 const Double& double_value = Double::ZoneHandle(Z, CurrentDoubleLiteral()); | 13914 const Double& double_value = Double::ZoneHandle(Z, CurrentDoubleLiteral()); |
14570 if (double_value.IsNull()) { | 13915 if (double_value.IsNull()) { |
14571 ReportError("invalid double literal"); | 13916 ReportError("invalid double literal"); |
14572 } | 13917 } |
14573 primary = new(Z) LiteralNode(TokenPos(), double_value); | 13918 primary = new (Z) LiteralNode(TokenPos(), double_value); |
14574 ConsumeToken(); | 13919 ConsumeToken(); |
14575 } else if (token == Token::kSTRING) { | 13920 } else if (token == Token::kSTRING) { |
14576 primary = ParseStringLiteral(true); | 13921 primary = ParseStringLiteral(true); |
14577 } else if (token == Token::kNEW) { | 13922 } else if (token == Token::kNEW) { |
14578 ConsumeToken(); | 13923 ConsumeToken(); |
14579 primary = ParseNewOperator(Token::kNEW); | 13924 primary = ParseNewOperator(Token::kNEW); |
14580 } else if (token == Token::kCONST) { | 13925 } else if (token == Token::kCONST) { |
14581 if ((LookaheadToken(1) == Token::kLT) || | 13926 if ((LookaheadToken(1) == Token::kLT) || |
14582 (LookaheadToken(1) == Token::kLBRACK) || | 13927 (LookaheadToken(1) == Token::kLBRACK) || |
14583 (LookaheadToken(1) == Token::kINDEX) || | 13928 (LookaheadToken(1) == Token::kINDEX) || |
14584 (LookaheadToken(1) == Token::kLBRACE)) { | 13929 (LookaheadToken(1) == Token::kLBRACE)) { |
14585 primary = ParseCompoundLiteral(); | 13930 primary = ParseCompoundLiteral(); |
14586 } else { | 13931 } else { |
14587 ConsumeToken(); | 13932 ConsumeToken(); |
14588 primary = ParseNewOperator(Token::kCONST); | 13933 primary = ParseNewOperator(Token::kCONST); |
14589 } | 13934 } |
14590 } else if (token == Token::kLT || | 13935 } else if (token == Token::kLT || token == Token::kLBRACK || |
14591 token == Token::kLBRACK || | 13936 token == Token::kINDEX || token == Token::kLBRACE) { |
14592 token == Token::kINDEX || | |
14593 token == Token::kLBRACE) { | |
14594 primary = ParseCompoundLiteral(); | 13937 primary = ParseCompoundLiteral(); |
14595 } else if (token == Token::kHASH) { | 13938 } else if (token == Token::kHASH) { |
14596 primary = ParseSymbolLiteral(); | 13939 primary = ParseSymbolLiteral(); |
14597 } else if (token == Token::kSUPER) { | 13940 } else if (token == Token::kSUPER) { |
14598 if (current_function().is_static()) { | 13941 if (current_function().is_static()) { |
14599 ReportError("cannot access superclass from static method"); | 13942 ReportError("cannot access superclass from static method"); |
14600 } | 13943 } |
14601 if (current_class().SuperClass() == Class::null()) { | 13944 if (current_class().SuperClass() == Class::null()) { |
14602 ReportError("class '%s' does not have a superclass", | 13945 ReportError("class '%s' does not have a superclass", |
14603 String::Handle(Z, current_class().Name()).ToCString()); | 13946 String::Handle(Z, current_class().Name()).ToCString()); |
14604 } | 13947 } |
14605 const TokenPosition super_pos = TokenPos(); | 13948 const TokenPosition super_pos = TokenPos(); |
14606 ConsumeToken(); | 13949 ConsumeToken(); |
14607 if (CurrentToken() == Token::kPERIOD) { | 13950 if (CurrentToken() == Token::kPERIOD) { |
14608 ConsumeToken(); | 13951 ConsumeToken(); |
14609 const TokenPosition ident_pos = TokenPos(); | 13952 const TokenPosition ident_pos = TokenPos(); |
14610 const String& ident = *ExpectIdentifier("identifier expected"); | 13953 const String& ident = *ExpectIdentifier("identifier expected"); |
14611 if (CurrentToken() == Token::kLPAREN) { | 13954 if (CurrentToken() == Token::kLPAREN) { |
14612 primary = ParseSuperCall(ident); | 13955 primary = ParseSuperCall(ident); |
14613 } else { | 13956 } else { |
14614 primary = ParseSuperFieldAccess(ident, ident_pos); | 13957 primary = ParseSuperFieldAccess(ident, ident_pos); |
14615 } | 13958 } |
14616 } else if ((CurrentToken() == Token::kLBRACK) || | 13959 } else if ((CurrentToken() == Token::kLBRACK) || |
14617 Token::CanBeOverloaded(CurrentToken()) || | 13960 Token::CanBeOverloaded(CurrentToken()) || |
14618 (CurrentToken() == Token::kNE)) { | 13961 (CurrentToken() == Token::kNE)) { |
14619 primary = ParseSuperOperator(); | 13962 primary = ParseSuperOperator(); |
14620 } else if (CurrentToken() == Token::kQM_PERIOD) { | 13963 } else if (CurrentToken() == Token::kQM_PERIOD) { |
14621 ReportError("super call or super getter may not use ?."); | 13964 ReportError("super call or super getter may not use ?."); |
14622 } else { | 13965 } else { |
14623 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); | 13966 primary = new (Z) PrimaryNode(super_pos, Symbols::Super()); |
14624 } | 13967 } |
14625 } else { | 13968 } else { |
14626 UnexpectedToken(); | 13969 UnexpectedToken(); |
14627 } | 13970 } |
14628 return primary; | 13971 return primary; |
14629 } | 13972 } |
14630 | 13973 |
14631 | 13974 |
14632 // Evaluate expression in expr and return the value. The expression must | 13975 // Evaluate expression in expr and return the value. The expression must |
14633 // be a compile time constant. | 13976 // be a compile time constant. |
14634 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos, | 13977 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos, |
14635 AstNode* expr) { | 13978 AstNode* expr) { |
14636 NoReloadScope no_reload_scope(isolate(), thread()); | 13979 NoReloadScope no_reload_scope(isolate(), thread()); |
14637 NoOOBMessageScope no_msg_scope(thread()); | 13980 NoOOBMessageScope no_msg_scope(thread()); |
14638 if (expr->IsLiteralNode()) { | 13981 if (expr->IsLiteralNode()) { |
14639 return expr->AsLiteralNode()->literal(); | 13982 return expr->AsLiteralNode()->literal(); |
14640 } else if (expr->IsLoadLocalNode() && | 13983 } else if (expr->IsLoadLocalNode() && |
14641 expr->AsLoadLocalNode()->local().IsConst()) { | 13984 expr->AsLoadLocalNode()->local().IsConst()) { |
14642 return *expr->AsLoadLocalNode()->local().ConstValue(); | 13985 return *expr->AsLoadLocalNode()->local().ConstValue(); |
14643 } else if (expr->IsLoadStaticFieldNode()) { | 13986 } else if (expr->IsLoadStaticFieldNode()) { |
14644 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 13987 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
14645 // We already checked that this field is const and has been | 13988 // We already checked that this field is const and has been |
14646 // initialized. | 13989 // initialized. |
14647 ASSERT(field.is_const()); | 13990 ASSERT(field.is_const()); |
14648 ASSERT(field.StaticValue() != Object::sentinel().raw()); | 13991 ASSERT(field.StaticValue() != Object::sentinel().raw()); |
14649 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); | 13992 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); |
14650 return Instance::ZoneHandle(Z, field.StaticValue()); | 13993 return Instance::ZoneHandle(Z, field.StaticValue()); |
14651 } else if (expr->IsTypeNode()) { | 13994 } else if (expr->IsTypeNode()) { |
14652 AbstractType& type = | 13995 AbstractType& type = |
14653 AbstractType::ZoneHandle(Z, expr->AsTypeNode()->type().raw()); | 13996 AbstractType::ZoneHandle(Z, expr->AsTypeNode()->type().raw()); |
14654 ASSERT(type.IsInstantiated() && !type.IsMalformedOrMalbounded()); | 13997 ASSERT(type.IsInstantiated() && !type.IsMalformedOrMalbounded()); |
14655 return type; | 13998 return type; |
14656 } else if (expr->IsClosureNode()) { | 13999 } else if (expr->IsClosureNode()) { |
14657 const Function& func = expr->AsClosureNode()->function(); | 14000 const Function& func = expr->AsClosureNode()->function(); |
14658 ASSERT((func.IsImplicitStaticClosureFunction())); | 14001 ASSERT((func.IsImplicitStaticClosureFunction())); |
14659 Instance& closure = Instance::ZoneHandle(Z, func.ImplicitStaticClosure()); | 14002 Instance& closure = Instance::ZoneHandle(Z, func.ImplicitStaticClosure()); |
14660 closure = TryCanonicalize(closure, expr_pos); | 14003 closure = TryCanonicalize(closure, expr_pos); |
14661 return closure; | 14004 return closure; |
14662 } else { | 14005 } else { |
14663 ASSERT(expr->EvalConstExpr() != NULL); | 14006 ASSERT(expr->EvalConstExpr() != NULL); |
14664 Instance& value = Instance::ZoneHandle(Z); | 14007 Instance& value = Instance::ZoneHandle(Z); |
14665 if (GetCachedConstant(expr_pos, &value)) { | 14008 if (GetCachedConstant(expr_pos, &value)) { |
14666 return value; | 14009 return value; |
14667 } | 14010 } |
14668 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); | 14011 ReturnNode* ret = new (Z) ReturnNode(expr_pos, expr); |
14669 // Compile time constant expressions cannot reference anything from a | 14012 // Compile time constant expressions cannot reference anything from a |
14670 // local scope. | 14013 // local scope. |
14671 LocalScope* empty_scope = new(Z) LocalScope(NULL, 0, 0); | 14014 LocalScope* empty_scope = new (Z) LocalScope(NULL, 0, 0); |
14672 SequenceNode* seq = new(Z) SequenceNode(expr_pos, empty_scope); | 14015 SequenceNode* seq = new (Z) SequenceNode(expr_pos, empty_scope); |
14673 seq->Add(ret); | 14016 seq->Add(ret); |
14674 | 14017 |
14675 INC_STAT(thread_, num_execute_const, 1); | 14018 INC_STAT(thread_, num_execute_const, 1); |
14676 Object& result = Object::Handle(Z, Compiler::ExecuteOnce(seq)); | 14019 Object& result = Object::Handle(Z, Compiler::ExecuteOnce(seq)); |
14677 if (result.IsError()) { | 14020 if (result.IsError()) { |
14678 ReportErrors(Error::Cast(result), | 14021 ReportErrors(Error::Cast(result), script_, expr_pos, |
14679 script_, expr_pos, | |
14680 "error evaluating constant expression"); | 14022 "error evaluating constant expression"); |
14681 } | 14023 } |
14682 ASSERT(result.IsInstance() || result.IsNull()); | 14024 ASSERT(result.IsInstance() || result.IsNull()); |
14683 value ^= result.raw(); | 14025 value ^= result.raw(); |
14684 value = TryCanonicalize(value, expr_pos); | 14026 value = TryCanonicalize(value, expr_pos); |
14685 CacheConstantValue(expr_pos, value); | 14027 CacheConstantValue(expr_pos, value); |
14686 return value; | 14028 return value; |
14687 } | 14029 } |
14688 } | 14030 } |
14689 | 14031 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14788 } | 14130 } |
14789 } | 14131 } |
14790 ExpectToken(Token::kRPAREN); | 14132 ExpectToken(Token::kRPAREN); |
14791 } | 14133 } |
14792 | 14134 |
14793 | 14135 |
14794 void Parser::SkipCompoundLiteral() { | 14136 void Parser::SkipCompoundLiteral() { |
14795 if (CurrentToken() == Token::kLT) { | 14137 if (CurrentToken() == Token::kLT) { |
14796 SkipTypeArguments(); | 14138 SkipTypeArguments(); |
14797 } | 14139 } |
14798 if ((CurrentToken() == Token::kLBRACK) || | 14140 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { |
14799 (CurrentToken() == Token::kINDEX)) { | |
14800 SkipListLiteral(); | 14141 SkipListLiteral(); |
14801 } else if (CurrentToken() == Token::kLBRACE) { | 14142 } else if (CurrentToken() == Token::kLBRACE) { |
14802 SkipMapLiteral(); | 14143 SkipMapLiteral(); |
14803 } | 14144 } |
14804 } | 14145 } |
14805 | 14146 |
14806 | 14147 |
14807 void Parser::SkipSymbolLiteral() { | 14148 void Parser::SkipSymbolLiteral() { |
14808 ConsumeToken(); // Hash sign. | 14149 ConsumeToken(); // Hash sign. |
14809 if (IsIdentifier()) { | 14150 if (IsIdentifier()) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14928 while (true) { | 14269 while (true) { |
14929 const Token::Kind current_token = CurrentToken(); | 14270 const Token::Kind current_token = CurrentToken(); |
14930 if (current_token == Token::kCASCADE) { | 14271 if (current_token == Token::kCASCADE) { |
14931 ConsumeToken(); | 14272 ConsumeToken(); |
14932 if (CurrentToken() == Token::kLBRACK) { | 14273 if (CurrentToken() == Token::kLBRACK) { |
14933 continue; // Consume [ in next loop iteration. | 14274 continue; // Consume [ in next loop iteration. |
14934 } else { | 14275 } else { |
14935 ExpectIdentifier("identifier or [ expected after .."); | 14276 ExpectIdentifier("identifier or [ expected after .."); |
14936 } | 14277 } |
14937 } else if ((current_token == Token::kPERIOD) || | 14278 } else if ((current_token == Token::kPERIOD) || |
14938 (current_token == Token::kQM_PERIOD)) { | 14279 (current_token == Token::kQM_PERIOD)) { |
14939 ConsumeToken(); | 14280 ConsumeToken(); |
14940 ExpectIdentifier("identifier expected"); | 14281 ExpectIdentifier("identifier expected"); |
14941 } else if (current_token == Token::kLBRACK) { | 14282 } else if (current_token == Token::kLBRACK) { |
14942 ConsumeToken(); | 14283 ConsumeToken(); |
14943 SkipNestedExpr(); | 14284 SkipNestedExpr(); |
14944 ExpectToken(Token::kRBRACK); | 14285 ExpectToken(Token::kRBRACK); |
14945 } else if (IsArgumentPart()) { | 14286 } else if (IsArgumentPart()) { |
14946 SkipActualParameters(); | 14287 SkipActualParameters(); |
14947 } else { | 14288 } else { |
14948 break; | 14289 break; |
(...skipping 15 matching lines...) Expand all Loading... |
14964 } | 14305 } |
14965 } | 14306 } |
14966 SkipSelectors(); | 14307 SkipSelectors(); |
14967 if (IsIncrementOperator(CurrentToken())) { | 14308 if (IsIncrementOperator(CurrentToken())) { |
14968 ConsumeToken(); | 14309 ConsumeToken(); |
14969 } | 14310 } |
14970 } | 14311 } |
14971 | 14312 |
14972 | 14313 |
14973 void Parser::SkipUnaryExpr() { | 14314 void Parser::SkipUnaryExpr() { |
14974 if (IsPrefixOperator(CurrentToken()) || | 14315 if (IsPrefixOperator(CurrentToken()) || IsIncrementOperator(CurrentToken()) || |
14975 IsIncrementOperator(CurrentToken()) || | |
14976 IsAwaitKeyword()) { | 14316 IsAwaitKeyword()) { |
14977 ConsumeToken(); | 14317 ConsumeToken(); |
14978 SkipUnaryExpr(); | 14318 SkipUnaryExpr(); |
14979 } else { | 14319 } else { |
14980 SkipPostfixExpr(); | 14320 SkipPostfixExpr(); |
14981 } | 14321 } |
14982 } | 14322 } |
14983 | 14323 |
14984 | 14324 |
14985 void Parser::SkipBinaryExpr() { | 14325 void Parser::SkipBinaryExpr() { |
14986 SkipUnaryExpr(); | 14326 SkipUnaryExpr(); |
14987 const int min_prec = Token::Precedence(Token::kIFNULL); | 14327 const int min_prec = Token::Precedence(Token::kIFNULL); |
14988 const int max_prec = Token::Precedence(Token::kMUL); | 14328 const int max_prec = Token::Precedence(Token::kMUL); |
14989 while (((min_prec <= Token::Precedence(CurrentToken())) && | 14329 while (((min_prec <= Token::Precedence(CurrentToken())) && |
14990 (Token::Precedence(CurrentToken()) <= max_prec))) { | 14330 (Token::Precedence(CurrentToken()) <= max_prec))) { |
14991 if (CurrentToken() == Token::kIS) { | 14331 if (CurrentToken() == Token::kIS) { |
14992 ConsumeToken(); | 14332 ConsumeToken(); |
14993 if (CurrentToken() == Token::kNOT) { | 14333 if (CurrentToken() == Token::kNOT) { |
14994 ConsumeToken(); | 14334 ConsumeToken(); |
14995 } | 14335 } |
14996 SkipType(false); | 14336 SkipType(false); |
14997 } else if (CurrentToken() == Token::kAS) { | 14337 } else if (CurrentToken() == Token::kAS) { |
14998 ConsumeToken(); | 14338 ConsumeToken(); |
14999 SkipType(false); | 14339 SkipType(false); |
15000 } else { | 14340 } else { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15145 const ArgumentListNode& function_args, | 14485 const ArgumentListNode& function_args, |
15146 const LocalVariable* temp_for_last_arg, | 14486 const LocalVariable* temp_for_last_arg, |
15147 bool is_super_invocation) { | 14487 bool is_super_invocation) { |
15148 UNREACHABLE(); | 14488 UNREACHABLE(); |
15149 return NULL; | 14489 return NULL; |
15150 } | 14490 } |
15151 | 14491 |
15152 } // namespace dart | 14492 } // namespace dart |
15153 | 14493 |
15154 #endif // DART_PRECOMPILED_RUNTIME | 14494 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |