| 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 |