| 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 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| 11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
| 12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/flags.h" | 13 #include "vm/flags.h" |
| 14 #include "vm/growable_array.h" | 14 #include "vm/growable_array.h" |
| 15 #include "vm/longjump.h" | 15 #include "vm/longjump.h" |
| 16 #include "vm/native_entry.h" | 16 #include "vm/native_entry.h" |
| 17 #include "vm/object.h" | 17 #include "vm/object.h" |
| 18 #include "vm/object_store.h" | 18 #include "vm/object_store.h" |
| 19 #include "vm/resolver.h" | 19 #include "vm/resolver.h" |
| 20 #include "vm/scopes.h" | 20 #include "vm/scopes.h" |
| 21 #include "vm/symbols.h" |
| 21 | 22 |
| 22 namespace dart { | 23 namespace dart { |
| 23 | 24 |
| 24 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 25 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 25 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 26 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
| 26 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 27 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 27 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | 28 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
| 28 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); | 29 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
| 29 | 30 |
| 30 static void CheckedModeHandler(bool value) { | 31 static void CheckedModeHandler(bool value) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 stack_trace ^= Object::Clone(stack_trace, Heap::kOld); | 116 stack_trace ^= Object::Clone(stack_trace, Heap::kOld); |
| 116 } | 117 } |
| 117 return new ThrowNode(token_pos, | 118 return new ThrowNode(token_pos, |
| 118 new LiteralNode(token_pos, exception), | 119 new LiteralNode(token_pos, exception), |
| 119 new LiteralNode(token_pos, stack_trace)); | 120 new LiteralNode(token_pos, stack_trace)); |
| 120 } | 121 } |
| 121 | 122 |
| 122 | 123 |
| 123 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { | 124 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { |
| 124 return new LocalVariable(token_pos, | 125 return new LocalVariable(token_pos, |
| 125 String::ZoneHandle(String::NewSymbol(":expr_temp")), | 126 String::ZoneHandle(Symbols::New(":expr_temp")), |
| 126 Type::ZoneHandle(Type::DynamicType())); | 127 Type::ZoneHandle(Type::DynamicType())); |
| 127 } | 128 } |
| 128 | 129 |
| 129 | 130 |
| 130 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 131 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 131 ASSERT(node_sequence_ == NULL); | 132 ASSERT(node_sequence_ == NULL); |
| 132 ASSERT(node_sequence != NULL); | 133 ASSERT(node_sequence != NULL); |
| 133 node_sequence_ = node_sequence; | 134 node_sequence_ = node_sequence; |
| 134 const int num_fixed_params = function().num_fixed_parameters(); | 135 const int num_fixed_params = function().num_fixed_parameters(); |
| 135 const int num_opt_params = function().num_optional_parameters(); | 136 const int num_opt_params = function().num_optional_parameters(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 parameter_count, | 182 parameter_count, |
| 182 first_stack_local_index_, | 183 first_stack_local_index_, |
| 183 scope, | 184 scope, |
| 184 &context_owner); | 185 &context_owner); |
| 185 | 186 |
| 186 // If this function is not a closure function and if it contains captured | 187 // If this function is not a closure function and if it contains captured |
| 187 // variables, the context needs to be saved on entry and restored on exit. | 188 // variables, the context needs to be saved on entry and restored on exit. |
| 188 // Add and allocate a local variable to this purpose. | 189 // Add and allocate a local variable to this purpose. |
| 189 if ((context_owner != NULL) && !function().IsClosureFunction()) { | 190 if ((context_owner != NULL) && !function().IsClosureFunction()) { |
| 190 const String& context_var_name = String::ZoneHandle( | 191 const String& context_var_name = String::ZoneHandle( |
| 191 String::NewSymbol(LocalVariable::kSavedContextVarName)); | 192 Symbols::New(LocalVariable::kSavedContextVarName)); |
| 192 LocalVariable* context_var = | 193 LocalVariable* context_var = |
| 193 new LocalVariable(function().token_pos(), | 194 new LocalVariable(function().token_pos(), |
| 194 context_var_name, | 195 context_var_name, |
| 195 Type::ZoneHandle(Type::DynamicType())); | 196 Type::ZoneHandle(Type::DynamicType())); |
| 196 context_var->set_index(next_free_frame_index--); | 197 context_var->set_index(next_free_frame_index--); |
| 197 scope->AddVariable(context_var); | 198 scope->AddVariable(context_var); |
| 198 set_saved_context_var(context_var); | 199 set_saved_context_var(context_var); |
| 199 } | 200 } |
| 200 | 201 |
| 201 // Frame indices are relative to the frame pointer and are decreasing. | 202 // Frame indices are relative to the frame pointer and are decreasing. |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 implicitly_final = false; | 431 implicitly_final = false; |
| 431 this->parameters = new ZoneGrowableArray<ParamDesc>(); | 432 this->parameters = new ZoneGrowableArray<ParamDesc>(); |
| 432 } | 433 } |
| 433 | 434 |
| 434 void AddFinalParameter(intptr_t name_pos, | 435 void AddFinalParameter(intptr_t name_pos, |
| 435 const char* name, | 436 const char* name, |
| 436 const AbstractType* type) { | 437 const AbstractType* type) { |
| 437 this->num_fixed_parameters++; | 438 this->num_fixed_parameters++; |
| 438 ParamDesc param; | 439 ParamDesc param; |
| 439 param.name_pos = name_pos; | 440 param.name_pos = name_pos; |
| 440 param.name = &String::ZoneHandle(String::NewSymbol(name)); | 441 param.name = &String::ZoneHandle(Symbols::New(name)); |
| 441 param.is_final = true; | 442 param.is_final = true; |
| 442 param.type = type; | 443 param.type = type; |
| 443 this->parameters->Add(param); | 444 this->parameters->Add(param); |
| 444 } | 445 } |
| 445 | 446 |
| 446 void AddReceiver(intptr_t name_pos) { | 447 void AddReceiver(intptr_t name_pos) { |
| 447 ASSERT(this->parameters->is_empty()); | 448 ASSERT(this->parameters->is_empty()); |
| 448 // The receiver does not need to be type checked. | 449 // The receiver does not need to be type checked. |
| 449 AddFinalParameter(name_pos, | 450 AddFinalParameter(name_pos, |
| 450 kThisName, | 451 kThisName, |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 811 // accesses to the field do not throw again, since initializers should only | 812 // accesses to the field do not throw again, since initializers should only |
| 812 // be executed once. | 813 // be executed once. |
| 813 SequenceNode* report_circular = new SequenceNode(TokenPos(), NULL); | 814 SequenceNode* report_circular = new SequenceNode(TokenPos(), NULL); |
| 814 report_circular->Add( | 815 report_circular->Add( |
| 815 new StoreStaticFieldNode( | 816 new StoreStaticFieldNode( |
| 816 TokenPos(), | 817 TokenPos(), |
| 817 field, | 818 field, |
| 818 new LiteralNode(TokenPos(), Instance::ZoneHandle()))); | 819 new LiteralNode(TokenPos(), Instance::ZoneHandle()))); |
| 819 // TODO(regis): Exception to throw is not specified by spec. | 820 // TODO(regis): Exception to throw is not specified by spec. |
| 820 const String& circular_error = String::ZoneHandle( | 821 const String& circular_error = String::ZoneHandle( |
| 821 String::NewSymbol("circular dependency in field initialization")); | 822 Symbols::New("circular dependency in field initialization")); |
| 822 report_circular->Add( | 823 report_circular->Add( |
| 823 new ThrowNode(TokenPos(), | 824 new ThrowNode(TokenPos(), |
| 824 new LiteralNode(TokenPos(), circular_error), | 825 new LiteralNode(TokenPos(), circular_error), |
| 825 NULL)); | 826 NULL)); |
| 826 AstNode* circular_check = | 827 AstNode* circular_check = |
| 827 new IfNode(TokenPos(), compare_circular, report_circular, NULL); | 828 new IfNode(TokenPos(), compare_circular, report_circular, NULL); |
| 828 current_block_->statements->Add(circular_check); | 829 current_block_->statements->Add(circular_check); |
| 829 | 830 |
| 830 // Generate code checking for uninitialized field. | 831 // Generate code checking for uninitialized field. |
| 831 AstNode* compare_uninitialized = new ComparisonNode( | 832 AstNode* compare_uninitialized = new ComparisonNode( |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 const Class& super_class = Class::Handle(current_class().SuperClass()); | 1236 const Class& super_class = Class::Handle(current_class().SuperClass()); |
| 1236 if (super_class.IsNull()) { | 1237 if (super_class.IsNull()) { |
| 1237 ErrorMsg(token_pos, "class '%s' does not have a superclass", | 1238 ErrorMsg(token_pos, "class '%s' does not have a superclass", |
| 1238 String::Handle(current_class().Name()).ToCString()); | 1239 String::Handle(current_class().Name()).ToCString()); |
| 1239 } | 1240 } |
| 1240 | 1241 |
| 1241 Function& super_func = | 1242 Function& super_func = |
| 1242 Function::Handle(ResolveDynamicFunction(super_class, name)); | 1243 Function::Handle(ResolveDynamicFunction(super_class, name)); |
| 1243 if (super_func.IsNull()) { | 1244 if (super_func.IsNull()) { |
| 1244 const String& no_such_method_name = | 1245 const String& no_such_method_name = |
| 1245 String::ZoneHandle(String::NewSymbol(kNoSuchMethodName)); | 1246 String::ZoneHandle(Symbols::New(kNoSuchMethodName)); |
| 1246 super_func = ResolveDynamicFunction(super_class, no_such_method_name); | 1247 super_func = ResolveDynamicFunction(super_class, no_such_method_name); |
| 1247 ASSERT(!super_func.IsNull()); | 1248 ASSERT(!super_func.IsNull()); |
| 1248 *is_no_such_method = true; | 1249 *is_no_such_method = true; |
| 1249 } else { | 1250 } else { |
| 1250 *is_no_such_method = false; | 1251 *is_no_such_method = false; |
| 1251 } | 1252 } |
| 1252 CheckFunctionIsCallable(token_pos, super_func); | 1253 CheckFunctionIsCallable(token_pos, super_func); |
| 1253 return super_func.raw(); | 1254 return super_func.raw(); |
| 1254 } | 1255 } |
| 1255 | 1256 |
| 1256 | 1257 |
| 1257 // Lookup class in the corelib implementation which contains various VM | 1258 // Lookup class in the corelib implementation which contains various VM |
| 1258 // helper methods and classes. | 1259 // helper methods and classes. |
| 1259 static RawClass* LookupImplClass(const String& class_name) { | 1260 static RawClass* LookupImplClass(const String& class_name) { |
| 1260 return Library::Handle(Library::CoreImplLibrary()).LookupClass(class_name); | 1261 return Library::Handle(Library::CoreImplLibrary()).LookupClass(class_name); |
| 1261 } | 1262 } |
| 1262 | 1263 |
| 1263 | 1264 |
| 1264 // Lookup class in the corelib which also contains various VM | 1265 // Lookup class in the corelib which also contains various VM |
| 1265 // helper methods and classes. Allow look up of private classes. | 1266 // helper methods and classes. Allow look up of private classes. |
| 1266 static RawClass* LookupCoreClass(const String& class_name) { | 1267 static RawClass* LookupCoreClass(const String& class_name) { |
| 1267 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1268 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1268 String& name = String::Handle(class_name.raw()); | 1269 String& name = String::Handle(class_name.raw()); |
| 1269 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { | 1270 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { |
| 1270 // Private identifiers are mangled on a per script basis. | 1271 // Private identifiers are mangled on a per script basis. |
| 1271 name = String::Concat(name, String::Handle(core_lib.private_key())); | 1272 name = String::Concat(name, String::Handle(core_lib.private_key())); |
| 1272 name = String::NewSymbol(name); | 1273 name = Symbols::New(name); |
| 1273 } | 1274 } |
| 1274 return core_lib.LookupClass(name); | 1275 return core_lib.LookupClass(name); |
| 1275 } | 1276 } |
| 1276 | 1277 |
| 1277 | 1278 |
| 1278 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 1279 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
| 1279 const String& function_name, | 1280 const String& function_name, |
| 1280 const ArgumentListNode& function_args) { | 1281 const ArgumentListNode& function_args) { |
| 1281 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 1282 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
| 1282 const intptr_t args_pos = function_args.token_pos(); | 1283 const intptr_t args_pos = function_args.token_pos(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); | 1349 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); |
| 1349 AstNode* save = | 1350 AstNode* save = |
| 1350 new StoreLocalNode(operator_pos, *temp, index_expr); | 1351 new StoreLocalNode(operator_pos, *temp, index_expr); |
| 1351 current_block_->statements->Add(save); | 1352 current_block_->statements->Add(save); |
| 1352 index_expr = new LoadLocalNode(operator_pos, *temp); | 1353 index_expr = new LoadLocalNode(operator_pos, *temp); |
| 1353 } | 1354 } |
| 1354 } | 1355 } |
| 1355 | 1356 |
| 1356 // Resolve the [] operator function in the superclass. | 1357 // Resolve the [] operator function in the superclass. |
| 1357 const String& index_operator_name = | 1358 const String& index_operator_name = |
| 1358 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); | 1359 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
| 1359 bool is_no_such_method = false; | 1360 bool is_no_such_method = false; |
| 1360 const Function& index_operator = Function::ZoneHandle( | 1361 const Function& index_operator = Function::ZoneHandle( |
| 1361 GetSuperFunction(operator_pos, | 1362 GetSuperFunction(operator_pos, |
| 1362 index_operator_name, | 1363 index_operator_name, |
| 1363 &is_no_such_method)); | 1364 &is_no_such_method)); |
| 1364 | 1365 |
| 1365 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos); | 1366 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos); |
| 1366 AstNode* receiver = LoadReceiver(operator_pos); | 1367 AstNode* receiver = LoadReceiver(operator_pos); |
| 1367 index_op_arguments->Add(receiver); | 1368 index_op_arguments->Add(receiver); |
| 1368 index_op_arguments->Add(index_expr); | 1369 index_op_arguments->Add(index_expr); |
| 1369 | 1370 |
| 1370 if (is_no_such_method) { | 1371 if (is_no_such_method) { |
| 1371 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name, | 1372 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name, |
| 1372 *index_op_arguments); | 1373 *index_op_arguments); |
| 1373 } | 1374 } |
| 1374 super_op = new StaticCallNode( | 1375 super_op = new StaticCallNode( |
| 1375 operator_pos, index_operator, index_op_arguments); | 1376 operator_pos, index_operator, index_op_arguments); |
| 1376 | 1377 |
| 1377 if (Token::IsAssignmentOperator(CurrentToken())) { | 1378 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 1378 Token::Kind assignment_op = CurrentToken(); | 1379 Token::Kind assignment_op = CurrentToken(); |
| 1379 ConsumeToken(); | 1380 ConsumeToken(); |
| 1380 AstNode* value = ParseExpr(kAllowConst); | 1381 AstNode* value = ParseExpr(kAllowConst); |
| 1381 | 1382 |
| 1382 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); | 1383 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); |
| 1383 | 1384 |
| 1384 // Resolve the []= operator function in the superclass. | 1385 // Resolve the []= operator function in the superclass. |
| 1385 const String& assign_index_operator_name = String::ZoneHandle( | 1386 const String& assign_index_operator_name = String::ZoneHandle( |
| 1386 String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 1387 Symbols::New(Token::Str(Token::kASSIGN_INDEX))); |
| 1387 bool is_no_such_method = false; | 1388 bool is_no_such_method = false; |
| 1388 const Function& assign_index_operator = Function::ZoneHandle( | 1389 const Function& assign_index_operator = Function::ZoneHandle( |
| 1389 GetSuperFunction(operator_pos, | 1390 GetSuperFunction(operator_pos, |
| 1390 assign_index_operator_name, | 1391 assign_index_operator_name, |
| 1391 &is_no_such_method)); | 1392 &is_no_such_method)); |
| 1392 | 1393 |
| 1393 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos); | 1394 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos); |
| 1394 operator_args->Add(LoadReceiver(operator_pos)); | 1395 operator_args->Add(LoadReceiver(operator_pos)); |
| 1395 operator_args->Add(index_expr); | 1396 operator_args->Add(index_expr); |
| 1396 operator_args->Add(value); | 1397 operator_args->Add(value); |
| 1397 | 1398 |
| 1398 if (is_no_such_method) { | 1399 if (is_no_such_method) { |
| 1399 operator_args = BuildNoSuchMethodArguments(assign_index_operator_name, | 1400 operator_args = BuildNoSuchMethodArguments(assign_index_operator_name, |
| 1400 *operator_args); | 1401 *operator_args); |
| 1401 } | 1402 } |
| 1402 super_op = new StaticCallNode( | 1403 super_op = new StaticCallNode( |
| 1403 operator_pos, assign_index_operator, operator_args); | 1404 operator_pos, assign_index_operator, operator_args); |
| 1404 } | 1405 } |
| 1405 } else if (Token::CanBeOverloaded(CurrentToken())) { | 1406 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 1406 Token::Kind op = CurrentToken(); | 1407 Token::Kind op = CurrentToken(); |
| 1407 ConsumeToken(); | 1408 ConsumeToken(); |
| 1408 | 1409 |
| 1409 // Resolve the operator function in the superclass. | 1410 // Resolve the operator function in the superclass. |
| 1410 const String& operator_function_name = | 1411 const String& operator_function_name = |
| 1411 String::Handle(String::NewSymbol(Token::Str(op))); | 1412 String::Handle(Symbols::New(Token::Str(op))); |
| 1412 bool is_no_such_method = false; | 1413 bool is_no_such_method = false; |
| 1413 const Function& super_operator = Function::ZoneHandle( | 1414 const Function& super_operator = Function::ZoneHandle( |
| 1414 GetSuperFunction(operator_pos, | 1415 GetSuperFunction(operator_pos, |
| 1415 operator_function_name, | 1416 operator_function_name, |
| 1416 &is_no_such_method)); | 1417 &is_no_such_method)); |
| 1417 | 1418 |
| 1418 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); | 1419 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); |
| 1419 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); | 1420 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); |
| 1420 | 1421 |
| 1421 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); | 1422 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 LocalVariable* receiver) { | 1522 LocalVariable* receiver) { |
| 1522 const intptr_t supercall_pos = TokenPos(); | 1523 const intptr_t supercall_pos = TokenPos(); |
| 1523 const Class& super_class = Class::Handle(cls.SuperClass()); | 1524 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1524 // Omit the implicit super() if there is no super class (i.e. | 1525 // Omit the implicit super() if there is no super class (i.e. |
| 1525 // we're not compiling class Object), or if the super class is an | 1526 // we're not compiling class Object), or if the super class is an |
| 1526 // artificially generated "wrapper class" that has no constructor. | 1527 // artificially generated "wrapper class" that has no constructor. |
| 1527 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { | 1528 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { |
| 1528 return; | 1529 return; |
| 1529 } | 1530 } |
| 1530 String& ctor_name = String::Handle(super_class.Name()); | 1531 String& ctor_name = String::Handle(super_class.Name()); |
| 1531 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1532 String& ctor_suffix = String::Handle(Symbols::Dot()); |
| 1532 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1533 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| 1533 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1534 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1534 // Implicit 'this' parameter is the first argument. | 1535 // Implicit 'this' parameter is the first argument. |
| 1535 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); | 1536 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); |
| 1536 arguments->Add(implicit_argument); | 1537 arguments->Add(implicit_argument); |
| 1537 // Implicit construction phase parameter is second argument. | 1538 // Implicit construction phase parameter is second argument. |
| 1538 AstNode* phase_parameter = | 1539 AstNode* phase_parameter = |
| 1539 new LiteralNode(supercall_pos, | 1540 new LiteralNode(supercall_pos, |
| 1540 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); | 1541 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
| 1541 arguments->Add(phase_parameter); | 1542 arguments->Add(phase_parameter); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1563 | 1564 |
| 1564 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 1565 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
| 1565 LocalVariable* receiver) { | 1566 LocalVariable* receiver) { |
| 1566 TRACE_PARSER("ParseSuperInitializer"); | 1567 TRACE_PARSER("ParseSuperInitializer"); |
| 1567 ASSERT(CurrentToken() == Token::kSUPER); | 1568 ASSERT(CurrentToken() == Token::kSUPER); |
| 1568 const intptr_t supercall_pos = TokenPos(); | 1569 const intptr_t supercall_pos = TokenPos(); |
| 1569 ConsumeToken(); | 1570 ConsumeToken(); |
| 1570 const Class& super_class = Class::Handle(cls.SuperClass()); | 1571 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1571 ASSERT(!super_class.IsNull()); | 1572 ASSERT(!super_class.IsNull()); |
| 1572 String& ctor_name = String::Handle(super_class.Name()); | 1573 String& ctor_name = String::Handle(super_class.Name()); |
| 1573 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1574 String& ctor_suffix = String::Handle(Symbols::Dot()); |
| 1574 if (CurrentToken() == Token::kPERIOD) { | 1575 if (CurrentToken() == Token::kPERIOD) { |
| 1575 ConsumeToken(); | 1576 ConsumeToken(); |
| 1576 ctor_suffix = String::Concat( | 1577 ctor_suffix = String::Concat( |
| 1577 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1578 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| 1578 } | 1579 } |
| 1579 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1580 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| 1580 if (CurrentToken() != Token::kLPAREN) { | 1581 if (CurrentToken() != Token::kLPAREN) { |
| 1581 ErrorMsg("parameter list expected"); | 1582 ErrorMsg("parameter list expected"); |
| 1582 } | 1583 } |
| 1583 | 1584 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1749 } | 1750 } |
| 1750 | 1751 |
| 1751 | 1752 |
| 1752 void Parser::ParseConstructorRedirection(const Class& cls, | 1753 void Parser::ParseConstructorRedirection(const Class& cls, |
| 1753 LocalVariable* receiver) { | 1754 LocalVariable* receiver) { |
| 1754 TRACE_PARSER("ParseConstructorRedirection"); | 1755 TRACE_PARSER("ParseConstructorRedirection"); |
| 1755 ASSERT(CurrentToken() == Token::kTHIS); | 1756 ASSERT(CurrentToken() == Token::kTHIS); |
| 1756 const intptr_t call_pos = TokenPos(); | 1757 const intptr_t call_pos = TokenPos(); |
| 1757 ConsumeToken(); | 1758 ConsumeToken(); |
| 1758 String& ctor_name = String::Handle(cls.Name()); | 1759 String& ctor_name = String::Handle(cls.Name()); |
| 1759 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1760 String& ctor_suffix = String::Handle(Symbols::Dot()); |
| 1760 | 1761 |
| 1761 if (CurrentToken() == Token::kPERIOD) { | 1762 if (CurrentToken() == Token::kPERIOD) { |
| 1762 ConsumeToken(); | 1763 ConsumeToken(); |
| 1763 ctor_suffix = String::Concat( | 1764 ctor_suffix = String::Concat( |
| 1764 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1765 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| 1765 } | 1766 } |
| 1766 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1767 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| 1767 if (CurrentToken() != Token::kLPAREN) { | 1768 if (CurrentToken() != Token::kLPAREN) { |
| 1768 ErrorMsg("parameter list expected"); | 1769 ErrorMsg("parameter list expected"); |
| 1769 } | 1770 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1808 OpenFunctionBlock(func); | 1809 OpenFunctionBlock(func); |
| 1809 | 1810 |
| 1810 // Parse expressions of instance fields that have an explicit | 1811 // Parse expressions of instance fields that have an explicit |
| 1811 // initializers. | 1812 // initializers. |
| 1812 GrowableArray<FieldInitExpression> initializers; | 1813 GrowableArray<FieldInitExpression> initializers; |
| 1813 Class& cls = Class::Handle(func.owner()); | 1814 Class& cls = Class::Handle(func.owner()); |
| 1814 ParseInitializedInstanceFields(cls, &initializers); | 1815 ParseInitializedInstanceFields(cls, &initializers); |
| 1815 | 1816 |
| 1816 LocalVariable* receiver = new LocalVariable( | 1817 LocalVariable* receiver = new LocalVariable( |
| 1817 ctor_pos, | 1818 ctor_pos, |
| 1818 String::ZoneHandle(String::NewSymbol(kThisName)), | 1819 String::ZoneHandle(Symbols::New(kThisName)), |
| 1819 Type::ZoneHandle(Type::DynamicType())); | 1820 Type::ZoneHandle(Type::DynamicType())); |
| 1820 current_block_->scope->AddVariable(receiver); | 1821 current_block_->scope->AddVariable(receiver); |
| 1821 | 1822 |
| 1822 LocalVariable* phase_parameter = new LocalVariable( | 1823 LocalVariable* phase_parameter = new LocalVariable( |
| 1823 ctor_pos, | 1824 ctor_pos, |
| 1824 String::ZoneHandle(String::NewSymbol(kPhaseParameterName)), | 1825 String::ZoneHandle(Symbols::New(kPhaseParameterName)), |
| 1825 Type::ZoneHandle(Type::DynamicType())); | 1826 Type::ZoneHandle(Type::DynamicType())); |
| 1826 current_block_->scope->AddVariable(phase_parameter); | 1827 current_block_->scope->AddVariable(phase_parameter); |
| 1827 | 1828 |
| 1828 // Now that the "this" parameter is in scope, we can generate the code | 1829 // Now that the "this" parameter is in scope, we can generate the code |
| 1829 // to strore the initializer expressions in the respective instance fields. | 1830 // to strore the initializer expressions in the respective instance fields. |
| 1830 for (int i = 0; i < initializers.length(); i++) { | 1831 for (int i = 0; i < initializers.length(); i++) { |
| 1831 const Field* field = initializers[i].inst_field; | 1832 const Field* field = initializers[i].inst_field; |
| 1832 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); | 1833 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); |
| 1833 AstNode* field_init = | 1834 AstNode* field_init = |
| 1834 new StoreInstanceFieldNode(field->token_pos(), | 1835 new StoreInstanceFieldNode(field->token_pos(), |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2368 if (method->params.has_field_initializer) { | 2369 if (method->params.has_field_initializer) { |
| 2369 // Constructors that redirect to another constructor must not | 2370 // Constructors that redirect to another constructor must not |
| 2370 // initialize any fields using field initializer parameters. | 2371 // initialize any fields using field initializer parameters. |
| 2371 ErrorMsg(formal_param_pos, "Redirecting constructor " | 2372 ErrorMsg(formal_param_pos, "Redirecting constructor " |
| 2372 "may not use field initializer parameters"); | 2373 "may not use field initializer parameters"); |
| 2373 } | 2374 } |
| 2374 ConsumeToken(); // Colon. | 2375 ConsumeToken(); // Colon. |
| 2375 ExpectToken(Token::kTHIS); | 2376 ExpectToken(Token::kTHIS); |
| 2376 String& redir_name = String::ZoneHandle( | 2377 String& redir_name = String::ZoneHandle( |
| 2377 String::Concat(members->class_name(), | 2378 String::Concat(members->class_name(), |
| 2378 String::Handle(String::NewSymbol(".")))); | 2379 String::Handle(Symbols::Dot()))); |
| 2379 if (CurrentToken() == Token::kPERIOD) { | 2380 if (CurrentToken() == Token::kPERIOD) { |
| 2380 ConsumeToken(); | 2381 ConsumeToken(); |
| 2381 redir_name = String::Concat(redir_name, | 2382 redir_name = String::Concat(redir_name, |
| 2382 *ExpectIdentifier("constructor name expected")); | 2383 *ExpectIdentifier("constructor name expected")); |
| 2383 } | 2384 } |
| 2384 method->redirect_name = &redir_name; | 2385 method->redirect_name = &redir_name; |
| 2385 if (CurrentToken() != Token::kLPAREN) { | 2386 if (CurrentToken() != Token::kLPAREN) { |
| 2386 ErrorMsg("'(' expected"); | 2387 ErrorMsg("'(' expected"); |
| 2387 } | 2388 } |
| 2388 SkipToMatchingParenthesis(); | 2389 SkipToMatchingParenthesis(); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2704 member.type = &Type::ZoneHandle(Type::New(result_type_class, | 2705 member.type = &Type::ZoneHandle(Type::New(result_type_class, |
| 2705 TypeArguments::Handle(), | 2706 TypeArguments::Handle(), |
| 2706 factory_name.ident_pos)); | 2707 factory_name.ident_pos)); |
| 2707 } else { | 2708 } else { |
| 2708 member.name_pos = TokenPos(); | 2709 member.name_pos = TokenPos(); |
| 2709 member.name = CurrentLiteral(); | 2710 member.name = CurrentLiteral(); |
| 2710 ConsumeToken(); | 2711 ConsumeToken(); |
| 2711 } | 2712 } |
| 2712 // We must be dealing with a constructor or named constructor. | 2713 // We must be dealing with a constructor or named constructor. |
| 2713 member.kind = RawFunction::kConstructor; | 2714 member.kind = RawFunction::kConstructor; |
| 2714 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); | 2715 String& ctor_suffix = String::ZoneHandle(Symbols::Dot()); |
| 2715 if (CurrentToken() == Token::kPERIOD) { | 2716 if (CurrentToken() == Token::kPERIOD) { |
| 2716 // Named constructor. | 2717 // Named constructor. |
| 2717 ConsumeToken(); | 2718 ConsumeToken(); |
| 2718 const String* name = ExpectIdentifier("identifier expected"); | 2719 const String* name = ExpectIdentifier("identifier expected"); |
| 2719 ctor_suffix = String::Concat(ctor_suffix, *name); | 2720 ctor_suffix = String::Concat(ctor_suffix, *name); |
| 2720 } | 2721 } |
| 2721 *member.name = String::Concat(*member.name, ctor_suffix); | 2722 *member.name = String::Concat(*member.name, ctor_suffix); |
| 2722 // Ensure that names are symbols. | 2723 // Ensure that names are symbols. |
| 2723 *member.name = String::NewSymbol(*member.name); | 2724 *member.name = Symbols::New(*member.name); |
| 2724 if (member.type == NULL) { | 2725 if (member.type == NULL) { |
| 2725 ASSERT(!member.has_factory); | 2726 ASSERT(!member.has_factory); |
| 2726 // The body of the constructor cannot modify the type arguments of the | 2727 // The body of the constructor cannot modify the type arguments of the |
| 2727 // constructed instance, which is passed in as a hidden parameter. | 2728 // constructed instance, which is passed in as a hidden parameter. |
| 2728 // Therefore, there is no need to set the result type to be checked. | 2729 // Therefore, there is no need to set the result type to be checked. |
| 2729 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2730 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2730 } else { | 2731 } else { |
| 2731 // The type can only be already set in the factory case. | 2732 // The type can only be already set in the factory case. |
| 2732 if (!member.has_factory) { | 2733 if (!member.has_factory) { |
| 2733 ErrorMsg(member.name_pos, "constructor must not specify return type"); | 2734 ErrorMsg(member.name_pos, "constructor must not specify return type"); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2775 if (!Token::CanBeOverloaded(CurrentToken())) { | 2776 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 2776 ErrorMsg("invalid operator overloading"); | 2777 ErrorMsg("invalid operator overloading"); |
| 2777 } | 2778 } |
| 2778 if (member.has_static) { | 2779 if (member.has_static) { |
| 2779 ErrorMsg("operator overloading functions cannot be static"); | 2780 ErrorMsg("operator overloading functions cannot be static"); |
| 2780 } | 2781 } |
| 2781 operator_token = CurrentToken(); | 2782 operator_token = CurrentToken(); |
| 2782 member.kind = RawFunction::kRegularFunction; | 2783 member.kind = RawFunction::kRegularFunction; |
| 2783 member.name_pos = this->TokenPos(); | 2784 member.name_pos = this->TokenPos(); |
| 2784 member.name = | 2785 member.name = |
| 2785 &String::ZoneHandle(String::NewSymbol(Token::Str(operator_token))); | 2786 &String::ZoneHandle(Symbols::New(Token::Str(operator_token))); |
| 2786 ConsumeToken(); | 2787 ConsumeToken(); |
| 2787 } else if (IsIdentifier()) { | 2788 } else if (IsIdentifier()) { |
| 2788 member.name = CurrentLiteral(); | 2789 member.name = CurrentLiteral(); |
| 2789 member.name_pos = TokenPos(); | 2790 member.name_pos = TokenPos(); |
| 2790 ConsumeToken(); | 2791 ConsumeToken(); |
| 2791 } else { | 2792 } else { |
| 2792 ErrorMsg("identifier expected"); | 2793 ErrorMsg("identifier expected"); |
| 2793 } | 2794 } |
| 2794 | 2795 |
| 2795 ASSERT(member.name != NULL); | 2796 ASSERT(member.name != NULL); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2920 | 2921 |
| 2921 // 1. Add an implicit constructor if no explicit constructor is present. | 2922 // 1. Add an implicit constructor if no explicit constructor is present. |
| 2922 // 2. Check for cycles in constructor redirection. | 2923 // 2. Check for cycles in constructor redirection. |
| 2923 void Parser::CheckConstructors(ClassDesc* class_desc) { | 2924 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 2924 // Add an implicit constructor if no explicit constructor is present. | 2925 // Add an implicit constructor if no explicit constructor is present. |
| 2925 if (!class_desc->has_constructor()) { | 2926 if (!class_desc->has_constructor()) { |
| 2926 // The implicit constructor is unnamed, has no explicit parameter, | 2927 // The implicit constructor is unnamed, has no explicit parameter, |
| 2927 // and contains a supercall in the initializer list. | 2928 // and contains a supercall in the initializer list. |
| 2928 String& ctor_name = String::ZoneHandle( | 2929 String& ctor_name = String::ZoneHandle( |
| 2929 String::Concat(class_desc->class_name(), | 2930 String::Concat(class_desc->class_name(), |
| 2930 String::Handle(String::NewSymbol(".")))); | 2931 String::Handle(Symbols::Dot()))); |
| 2931 ctor_name = String::NewSymbol(ctor_name); | 2932 ctor_name = Symbols::New(ctor_name); |
| 2932 // The token position for the implicit constructor is the 'class' | 2933 // The token position for the implicit constructor is the 'class' |
| 2933 // keyword of the constructor's class. | 2934 // keyword of the constructor's class. |
| 2934 Function& ctor = Function::Handle( | 2935 Function& ctor = Function::Handle( |
| 2935 Function::New(ctor_name, | 2936 Function::New(ctor_name, |
| 2936 RawFunction::kConstructor, | 2937 RawFunction::kConstructor, |
| 2937 /* is_static = */ false, | 2938 /* is_static = */ false, |
| 2938 /* is_const = */ false, | 2939 /* is_const = */ false, |
| 2939 class_desc->token_pos())); | 2940 class_desc->token_pos())); |
| 2940 ParamList params; | 2941 ParamList params; |
| 2941 // Add implicit 'this' parameter. | 2942 // Add implicit 'this' parameter. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3003 | 3004 |
| 3004 | 3005 |
| 3005 void Parser::ParseFunctionTypeAlias( | 3006 void Parser::ParseFunctionTypeAlias( |
| 3006 const GrowableObjectArray& pending_classes) { | 3007 const GrowableObjectArray& pending_classes) { |
| 3007 TRACE_PARSER("ParseFunctionTypeAlias"); | 3008 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 3008 ExpectToken(Token::kTYPEDEF); | 3009 ExpectToken(Token::kTYPEDEF); |
| 3009 | 3010 |
| 3010 // Allocate an interface to hold the type parameters and their bounds. | 3011 // Allocate an interface to hold the type parameters and their bounds. |
| 3011 // Make it the owner of the function type descriptor. | 3012 // Make it the owner of the function type descriptor. |
| 3012 const Class& alias_owner = Class::Handle( | 3013 const Class& alias_owner = Class::Handle( |
| 3013 Class::New(String::Handle(String::NewSymbol(":alias_owner")), | 3014 Class::New(String::Handle(Symbols::New(":alias_owner")), |
| 3014 Script::Handle(), | 3015 Script::Handle(), |
| 3015 TokenPos())); | 3016 TokenPos())); |
| 3016 alias_owner.set_is_interface(); | 3017 alias_owner.set_is_interface(); |
| 3017 alias_owner.set_library(library_); | 3018 alias_owner.set_library(library_); |
| 3018 set_current_class(alias_owner); | 3019 set_current_class(alias_owner); |
| 3019 | 3020 |
| 3020 // Parse the result type of the function type. | 3021 // Parse the result type of the function type. |
| 3021 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3022 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 3022 if (CurrentToken() == Token::kVOID) { | 3023 if (CurrentToken() == Token::kVOID) { |
| 3023 ConsumeToken(); | 3024 ConsumeToken(); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3156 ParseQualIdent(&factory_name); | 3157 ParseQualIdent(&factory_name); |
| 3157 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | 3158 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
| 3158 if (factory_name.lib_prefix != NULL) { | 3159 if (factory_name.lib_prefix != NULL) { |
| 3159 lib_prefix = factory_name.lib_prefix->raw(); | 3160 lib_prefix = factory_name.lib_prefix->raw(); |
| 3160 } | 3161 } |
| 3161 const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle( | 3162 const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle( |
| 3162 UnresolvedClass::New(lib_prefix, | 3163 UnresolvedClass::New(lib_prefix, |
| 3163 *factory_name.ident, | 3164 *factory_name.ident, |
| 3164 factory_name.ident_pos)); | 3165 factory_name.ident_pos)); |
| 3165 const Class& factory_class = Class::Handle( | 3166 const Class& factory_class = Class::Handle( |
| 3166 Class::New(String::Handle(String::NewSymbol(":factory_signature")), | 3167 Class::New(String::Handle(Symbols::New(":factory_signature")), |
| 3167 script_, | 3168 script_, |
| 3168 factory_name.ident_pos)); | 3169 factory_name.ident_pos)); |
| 3169 factory_class.set_library(library_); | 3170 factory_class.set_library(library_); |
| 3170 factory_class.set_is_finalized(); | 3171 factory_class.set_is_finalized(); |
| 3171 ParseTypeParameters(factory_class); | 3172 ParseTypeParameters(factory_class); |
| 3172 unresolved_factory_class.set_factory_signature_class(factory_class); | 3173 unresolved_factory_class.set_factory_signature_class(factory_class); |
| 3173 interface.set_factory_class(unresolved_factory_class); | 3174 interface.set_factory_class(unresolved_factory_class); |
| 3174 // If a type parameter list is included in the default factory clause (it | 3175 // If a type parameter list is included in the default factory clause (it |
| 3175 // can be omitted), verify that it matches the list of type parameters of | 3176 // can be omitted), verify that it matches the list of type parameters of |
| 3176 // the interface in number and names, but not necessarily in bounds. | 3177 // the interface in number and names, but not necessarily in bounds. |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3812 // They need to be registered with class finalization after parsing | 3813 // They need to be registered with class finalization after parsing |
| 3813 // has been completed. | 3814 // has been completed. |
| 3814 Isolate* isolate = Isolate::Current(); | 3815 Isolate* isolate = Isolate::Current(); |
| 3815 ObjectStore* object_store = isolate->object_store(); | 3816 ObjectStore* object_store = isolate->object_store(); |
| 3816 const GrowableObjectArray& pending_classes = | 3817 const GrowableObjectArray& pending_classes = |
| 3817 GrowableObjectArray::Handle(isolate, object_store->pending_classes()); | 3818 GrowableObjectArray::Handle(isolate, object_store->pending_classes()); |
| 3818 SetPosition(0); | 3819 SetPosition(0); |
| 3819 is_top_level_ = true; | 3820 is_top_level_ = true; |
| 3820 TopLevel top_level; | 3821 TopLevel top_level; |
| 3821 Class& toplevel_class = Class::Handle( | 3822 Class& toplevel_class = Class::Handle( |
| 3822 Class::New(String::ZoneHandle(String::NewSymbol("::")), | 3823 Class::New(String::ZoneHandle(Symbols::New("::")), |
| 3823 script_, | 3824 script_, |
| 3824 TokenPos())); | 3825 TokenPos())); |
| 3825 toplevel_class.set_library(library_); | 3826 toplevel_class.set_library(library_); |
| 3826 | 3827 |
| 3827 if (is_library_source()) { | 3828 if (is_library_source()) { |
| 3828 ParseLibraryDefinition(); | 3829 ParseLibraryDefinition(); |
| 3829 } | 3830 } |
| 3830 | 3831 |
| 3831 while (true) { | 3832 while (true) { |
| 3832 set_current_class(Class::Handle()); // No current class. | 3833 set_current_class(Class::Handle()); // No current class. |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4030 new ReturnNode(TokenPos(), new NativeBodyNode(TokenPos(), | 4031 new ReturnNode(TokenPos(), new NativeBodyNode(TokenPos(), |
| 4031 native_name, | 4032 native_name, |
| 4032 native_function, | 4033 native_function, |
| 4033 num_parameters, | 4034 num_parameters, |
| 4034 has_opt_params, | 4035 has_opt_params, |
| 4035 is_instance_closure))); | 4036 is_instance_closure))); |
| 4036 } | 4037 } |
| 4037 | 4038 |
| 4038 | 4039 |
| 4039 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 4040 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| 4040 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 4041 const String& this_name = String::Handle(Symbols::New(kThisName)); |
| 4041 return from_scope->LookupVariable(this_name, test_only); | 4042 return from_scope->LookupVariable(this_name, test_only); |
| 4042 } | 4043 } |
| 4043 | 4044 |
| 4044 | 4045 |
| 4045 LocalVariable* Parser::LookupPhaseParameter() { | 4046 LocalVariable* Parser::LookupPhaseParameter() { |
| 4046 const String& phase_name = | 4047 const String& phase_name = |
| 4047 String::Handle(String::NewSymbol(kPhaseParameterName)); | 4048 String::Handle(Symbols::New(kPhaseParameterName)); |
| 4048 const bool kTestOnly = false; | 4049 const bool kTestOnly = false; |
| 4049 return current_block_->scope->LookupVariable(phase_name, kTestOnly); | 4050 return current_block_->scope->LookupVariable(phase_name, kTestOnly); |
| 4050 } | 4051 } |
| 4051 | 4052 |
| 4052 | 4053 |
| 4053 void Parser::CaptureReceiver() { | 4054 void Parser::CaptureReceiver() { |
| 4054 ASSERT(current_block_->scope->function_level() > 0); | 4055 ASSERT(current_block_->scope->function_level() > 0); |
| 4055 const bool kTestOnly = false; | 4056 const bool kTestOnly = false; |
| 4056 // Side effect of lookup captures the receiver variable. | 4057 // Side effect of lookup captures the receiver variable. |
| 4057 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 4058 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4206 const intptr_t ident_pos = TokenPos(); | 4207 const intptr_t ident_pos = TokenPos(); |
| 4207 if (IsIdentifier()) { | 4208 if (IsIdentifier()) { |
| 4208 variable_name = CurrentLiteral(); | 4209 variable_name = CurrentLiteral(); |
| 4209 function_name = variable_name; | 4210 function_name = variable_name; |
| 4210 ConsumeToken(); | 4211 ConsumeToken(); |
| 4211 } else { | 4212 } else { |
| 4212 if (!is_literal) { | 4213 if (!is_literal) { |
| 4213 ErrorMsg("function name expected"); | 4214 ErrorMsg("function name expected"); |
| 4214 } | 4215 } |
| 4215 const String& anonymous_function_name = | 4216 const String& anonymous_function_name = |
| 4216 String::ZoneHandle(String::NewSymbol("function")); | 4217 String::ZoneHandle(Symbols::New("function")); |
| 4217 function_name = &anonymous_function_name; | 4218 function_name = &anonymous_function_name; |
| 4218 } | 4219 } |
| 4219 ASSERT(ident_pos >= 0); | 4220 ASSERT(ident_pos >= 0); |
| 4220 | 4221 |
| 4221 if (CurrentToken() != Token::kLPAREN) { | 4222 if (CurrentToken() != Token::kLPAREN) { |
| 4222 ErrorMsg("'(' expected"); | 4223 ErrorMsg("'(' expected"); |
| 4223 } | 4224 } |
| 4224 intptr_t function_pos = TokenPos(); | 4225 intptr_t function_pos = TokenPos(); |
| 4225 | 4226 |
| 4226 // Check whether we have parsed this closure function before, in a previous | 4227 // Check whether we have parsed this closure function before, in a previous |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4785 if (paren_found) { | 4786 if (paren_found) { |
| 4786 ExpectToken(Token::kRPAREN); | 4787 ExpectToken(Token::kRPAREN); |
| 4787 } | 4788 } |
| 4788 ExpectToken(Token::kLBRACE); | 4789 ExpectToken(Token::kLBRACE); |
| 4789 OpenBlock(); | 4790 OpenBlock(); |
| 4790 current_block_->scope->AddLabel(label); | 4791 current_block_->scope->AddLabel(label); |
| 4791 | 4792 |
| 4792 // Store switch expression in temporary local variable. | 4793 // Store switch expression in temporary local variable. |
| 4793 LocalVariable* temp_variable = | 4794 LocalVariable* temp_variable = |
| 4794 new LocalVariable(expr_pos, | 4795 new LocalVariable(expr_pos, |
| 4795 String::ZoneHandle(String::NewSymbol(":switch_expr")), | 4796 String::ZoneHandle(Symbols::New(":switch_expr")), |
| 4796 Type::ZoneHandle(Type::DynamicType())); | 4797 Type::ZoneHandle(Type::DynamicType())); |
| 4797 current_block_->scope->AddVariable(temp_variable); | 4798 current_block_->scope->AddVariable(temp_variable); |
| 4798 AstNode* save_switch_expr = | 4799 AstNode* save_switch_expr = |
| 4799 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); | 4800 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); |
| 4800 current_block_->statements->Add(save_switch_expr); | 4801 current_block_->statements->Add(save_switch_expr); |
| 4801 | 4802 |
| 4802 // Parse case clauses | 4803 // Parse case clauses |
| 4803 bool default_seen = false; | 4804 bool default_seen = false; |
| 4804 while (true) { | 4805 while (true) { |
| 4805 // Check for statement label | 4806 // Check for statement label |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4913 } | 4914 } |
| 4914 ExpectToken(Token::kIN); | 4915 ExpectToken(Token::kIN); |
| 4915 const intptr_t collection_pos = TokenPos(); | 4916 const intptr_t collection_pos = TokenPos(); |
| 4916 AstNode* collection_expr = ParseExpr(kAllowConst); | 4917 AstNode* collection_expr = ParseExpr(kAllowConst); |
| 4917 ExpectToken(Token::kRPAREN); | 4918 ExpectToken(Token::kRPAREN); |
| 4918 | 4919 |
| 4919 OpenBlock(); // Implicit block around while loop. | 4920 OpenBlock(); // Implicit block around while loop. |
| 4920 | 4921 |
| 4921 // Generate implicit iterator variable and add to scope. | 4922 // Generate implicit iterator variable and add to scope. |
| 4922 const String& iterator_name = | 4923 const String& iterator_name = |
| 4923 String::ZoneHandle(String::NewSymbol(":for-in-iter")); | 4924 String::ZoneHandle(Symbols::New(":for-in-iter")); |
| 4924 // We could set the type of the implicit iterator variable to Iterator<T> | 4925 // We could set the type of the implicit iterator variable to Iterator<T> |
| 4925 // where T is the type of the for loop variable. However, the type error | 4926 // where T is the type of the for loop variable. However, the type error |
| 4926 // would refer to the compiler generated iterator and could confuse the user. | 4927 // would refer to the compiler generated iterator and could confuse the user. |
| 4927 // It is better to leave the iterator untyped and postpone the type error | 4928 // It is better to leave the iterator untyped and postpone the type error |
| 4928 // until the loop variable is assigned to. | 4929 // until the loop variable is assigned to. |
| 4929 const AbstractType& iterator_type = Type::ZoneHandle(Type::DynamicType()); | 4930 const AbstractType& iterator_type = Type::ZoneHandle(Type::DynamicType()); |
| 4930 LocalVariable* iterator_var = | 4931 LocalVariable* iterator_var = |
| 4931 new LocalVariable(collection_pos, iterator_name, iterator_type); | 4932 new LocalVariable(collection_pos, iterator_name, iterator_type); |
| 4932 current_block_->scope->AddVariable(iterator_var); | 4933 current_block_->scope->AddVariable(iterator_var); |
| 4933 | 4934 |
| 4934 // Generate initialization of iterator variable. | 4935 // Generate initialization of iterator variable. |
| 4935 const String& iterator_method_name = | 4936 const String& iterator_method_name = |
| 4936 String::ZoneHandle(String::NewSymbol(kGetIteratorName)); | 4937 String::ZoneHandle(Symbols::New(kGetIteratorName)); |
| 4937 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); | 4938 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); |
| 4938 AstNode* get_iterator = new InstanceCallNode( | 4939 AstNode* get_iterator = new InstanceCallNode( |
| 4939 collection_pos, collection_expr, iterator_method_name, no_args); | 4940 collection_pos, collection_expr, iterator_method_name, no_args); |
| 4940 AstNode* iterator_init = | 4941 AstNode* iterator_init = |
| 4941 new StoreLocalNode(collection_pos, *iterator_var, get_iterator); | 4942 new StoreLocalNode(collection_pos, *iterator_var, get_iterator); |
| 4942 current_block_->statements->Add(iterator_init); | 4943 current_block_->statements->Add(iterator_init); |
| 4943 | 4944 |
| 4944 // Generate while loop condition. | 4945 // Generate while loop condition. |
| 4945 AstNode* iterator_has_next = new InstanceCallNode( | 4946 AstNode* iterator_has_next = new InstanceCallNode( |
| 4946 collection_pos, | 4947 collection_pos, |
| 4947 new LoadLocalNode(collection_pos, *iterator_var), | 4948 new LoadLocalNode(collection_pos, *iterator_var), |
| 4948 String::ZoneHandle(String::NewSymbol("hasNext")), | 4949 String::ZoneHandle(Symbols::New("hasNext")), |
| 4949 no_args); | 4950 no_args); |
| 4950 | 4951 |
| 4951 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 4952 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
| 4952 // here, but that does not work well because we have to insert an implicit | 4953 // here, but that does not work well because we have to insert an implicit |
| 4953 // variable assignment and potentially a variable declaration in the | 4954 // variable assignment and potentially a variable declaration in the |
| 4954 // loop body. | 4955 // loop body. |
| 4955 OpenLoopBlock(); | 4956 OpenLoopBlock(); |
| 4956 current_block_->scope->AddLabel(label); | 4957 current_block_->scope->AddLabel(label); |
| 4957 | 4958 |
| 4958 AstNode* iterator_next = new InstanceCallNode( | 4959 AstNode* iterator_next = new InstanceCallNode( |
| 4959 collection_pos, | 4960 collection_pos, |
| 4960 new LoadLocalNode(collection_pos, *iterator_var), | 4961 new LoadLocalNode(collection_pos, *iterator_var), |
| 4961 String::ZoneHandle(String::NewSymbol("next")), | 4962 String::ZoneHandle(Symbols::New("next")), |
| 4962 no_args); | 4963 no_args); |
| 4963 | 4964 |
| 4964 // Generate assignment of next iterator value to loop variable. | 4965 // Generate assignment of next iterator value to loop variable. |
| 4965 AstNode* loop_var_assignment = NULL; | 4966 AstNode* loop_var_assignment = NULL; |
| 4966 if (loop_var != NULL) { | 4967 if (loop_var != NULL) { |
| 4967 // The for loop declares a new variable. Add it to the loop body scope. | 4968 // The for loop declares a new variable. Add it to the loop body scope. |
| 4968 current_block_->scope->AddVariable(loop_var); | 4969 current_block_->scope->AddVariable(loop_var); |
| 4969 loop_var_assignment = | 4970 loop_var_assignment = |
| 4970 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); | 4971 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); |
| 4971 } else { | 4972 } else { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5066 NodeAsSequenceNode(incr_pos, increment, incr_scope), | 5067 NodeAsSequenceNode(incr_pos, increment, incr_scope), |
| 5067 body); | 5068 body); |
| 5068 } | 5069 } |
| 5069 | 5070 |
| 5070 | 5071 |
| 5071 // Calling VM-internal helpers, uses implementation core library. | 5072 // Calling VM-internal helpers, uses implementation core library. |
| 5072 AstNode* Parser::MakeStaticCall(const char* class_name, | 5073 AstNode* Parser::MakeStaticCall(const char* class_name, |
| 5073 const char* function_name, | 5074 const char* function_name, |
| 5074 ArgumentListNode* arguments) { | 5075 ArgumentListNode* arguments) { |
| 5075 const String& cls_name = | 5076 const String& cls_name = |
| 5076 String::Handle(String::NewSymbol(class_name)); | 5077 String::Handle(Symbols::New(class_name)); |
| 5077 const Class& cls = Class::Handle(LookupImplClass(cls_name)); | 5078 const Class& cls = Class::Handle(LookupImplClass(cls_name)); |
| 5078 ASSERT(!cls.IsNull()); | 5079 ASSERT(!cls.IsNull()); |
| 5079 const String& func_name = | 5080 const String& func_name = |
| 5080 String::ZoneHandle(String::NewSymbol(function_name)); | 5081 String::ZoneHandle(Symbols::New(function_name)); |
| 5081 const Function& func = Function::ZoneHandle( | 5082 const Function& func = Function::ZoneHandle( |
| 5082 Resolver::ResolveStatic(cls, | 5083 Resolver::ResolveStatic(cls, |
| 5083 func_name, | 5084 func_name, |
| 5084 arguments->length(), | 5085 arguments->length(), |
| 5085 arguments->names(), | 5086 arguments->names(), |
| 5086 Resolver::kIsQualified)); | 5087 Resolver::kIsQualified)); |
| 5087 ASSERT(!func.IsNull()); | 5088 ASSERT(!func.IsNull()); |
| 5088 CheckFunctionIsCallable(arguments->token_pos(), func); | 5089 CheckFunctionIsCallable(arguments->token_pos(), func); |
| 5089 return new StaticCallNode(arguments->token_pos(), func, arguments); | 5090 return new StaticCallNode(arguments->token_pos(), func, arguments); |
| 5090 } | 5091 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5266 // slot before processing the catch block handler. | 5267 // slot before processing the catch block handler. |
| 5267 // ':exception_var' - Used to save the current exception object that was | 5268 // ':exception_var' - Used to save the current exception object that was |
| 5268 // thrown. | 5269 // thrown. |
| 5269 // ':stacktrace_var' - Used to save the current stack trace object into which | 5270 // ':stacktrace_var' - Used to save the current stack trace object into which |
| 5270 // the stack trace was copied into when an exception was | 5271 // the stack trace was copied into when an exception was |
| 5271 // thrown. | 5272 // thrown. |
| 5272 // :exception_var and :stacktrace_var get set with the exception object | 5273 // :exception_var and :stacktrace_var get set with the exception object |
| 5273 // and the stacktrace object when an exception is thrown. | 5274 // and the stacktrace object when an exception is thrown. |
| 5274 // These three implicit variables can never be captured variables. | 5275 // These three implicit variables can never be captured variables. |
| 5275 const String& context_var_name = | 5276 const String& context_var_name = |
| 5276 String::ZoneHandle(String::NewSymbol(":saved_context_var")); | 5277 String::ZoneHandle(Symbols::New(":saved_context_var")); |
| 5277 LocalVariable* context_var = | 5278 LocalVariable* context_var = |
| 5278 current_block_->scope->LocalLookupVariable(context_var_name); | 5279 current_block_->scope->LocalLookupVariable(context_var_name); |
| 5279 if (context_var == NULL) { | 5280 if (context_var == NULL) { |
| 5280 context_var = new LocalVariable(TokenPos(), | 5281 context_var = new LocalVariable(TokenPos(), |
| 5281 context_var_name, | 5282 context_var_name, |
| 5282 Type::ZoneHandle(Type::DynamicType())); | 5283 Type::ZoneHandle(Type::DynamicType())); |
| 5283 current_block_->scope->AddVariable(context_var); | 5284 current_block_->scope->AddVariable(context_var); |
| 5284 } | 5285 } |
| 5285 const String& catch_excp_var_name = | 5286 const String& catch_excp_var_name = |
| 5286 String::ZoneHandle(String::NewSymbol(":exception_var")); | 5287 String::ZoneHandle(Symbols::New(":exception_var")); |
| 5287 LocalVariable* catch_excp_var = | 5288 LocalVariable* catch_excp_var = |
| 5288 current_block_->scope->LocalLookupVariable(catch_excp_var_name); | 5289 current_block_->scope->LocalLookupVariable(catch_excp_var_name); |
| 5289 if (catch_excp_var == NULL) { | 5290 if (catch_excp_var == NULL) { |
| 5290 catch_excp_var = new LocalVariable(TokenPos(), | 5291 catch_excp_var = new LocalVariable(TokenPos(), |
| 5291 catch_excp_var_name, | 5292 catch_excp_var_name, |
| 5292 Type::ZoneHandle(Type::DynamicType())); | 5293 Type::ZoneHandle(Type::DynamicType())); |
| 5293 current_block_->scope->AddVariable(catch_excp_var); | 5294 current_block_->scope->AddVariable(catch_excp_var); |
| 5294 } | 5295 } |
| 5295 const String& catch_trace_var_name = | 5296 const String& catch_trace_var_name = |
| 5296 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); | 5297 String::ZoneHandle(Symbols::New(":stacktrace_var")); |
| 5297 LocalVariable* catch_trace_var = | 5298 LocalVariable* catch_trace_var = |
| 5298 current_block_->scope->LocalLookupVariable(catch_trace_var_name); | 5299 current_block_->scope->LocalLookupVariable(catch_trace_var_name); |
| 5299 if (catch_trace_var == NULL) { | 5300 if (catch_trace_var == NULL) { |
| 5300 catch_trace_var = new LocalVariable(TokenPos(), | 5301 catch_trace_var = new LocalVariable(TokenPos(), |
| 5301 catch_trace_var_name, | 5302 catch_trace_var_name, |
| 5302 Type::ZoneHandle(Type::DynamicType())); | 5303 Type::ZoneHandle(Type::DynamicType())); |
| 5303 current_block_->scope->AddVariable(catch_trace_var); | 5304 current_block_->scope->AddVariable(catch_trace_var); |
| 5304 } | 5305 } |
| 5305 | 5306 |
| 5306 const intptr_t try_pos = TokenPos(); | 5307 const intptr_t try_pos = TokenPos(); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5655 // Check if it is ok to do a rethrow. | 5656 // Check if it is ok to do a rethrow. |
| 5656 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel(); | 5657 SourceLabel* label = current_block_->scope->LookupInnermostCatchLabel(); |
| 5657 if (label == NULL || | 5658 if (label == NULL || |
| 5658 label->FunctionLevel() != current_block_->scope->function_level()) { | 5659 label->FunctionLevel() != current_block_->scope->function_level()) { |
| 5659 ErrorMsg("rethrow of an exception is not valid here"); | 5660 ErrorMsg("rethrow of an exception is not valid here"); |
| 5660 } | 5661 } |
| 5661 ASSERT(label->owner() != NULL); | 5662 ASSERT(label->owner() != NULL); |
| 5662 LocalScope* scope = label->owner()->parent(); | 5663 LocalScope* scope = label->owner()->parent(); |
| 5663 ASSERT(scope != NULL); | 5664 ASSERT(scope != NULL); |
| 5664 LocalVariable* excp_var = scope->LocalLookupVariable( | 5665 LocalVariable* excp_var = scope->LocalLookupVariable( |
| 5665 String::ZoneHandle(String::NewSymbol(":exception_var"))); | 5666 String::ZoneHandle(Symbols::New(":exception_var"))); |
| 5666 ASSERT(excp_var != NULL); | 5667 ASSERT(excp_var != NULL); |
| 5667 LocalVariable* trace_var = scope->LocalLookupVariable( | 5668 LocalVariable* trace_var = scope->LocalLookupVariable( |
| 5668 String::ZoneHandle(String::NewSymbol(":stacktrace_var"))); | 5669 String::ZoneHandle(Symbols::New(":stacktrace_var"))); |
| 5669 ASSERT(trace_var != NULL); | 5670 ASSERT(trace_var != NULL); |
| 5670 statement = new ThrowNode(statement_pos, | 5671 statement = new ThrowNode(statement_pos, |
| 5671 new LoadLocalNode(statement_pos, *excp_var), | 5672 new LoadLocalNode(statement_pos, *excp_var), |
| 5672 new LoadLocalNode(statement_pos, *trace_var)); | 5673 new LoadLocalNode(statement_pos, *trace_var)); |
| 5673 } | 5674 } |
| 5674 } else { | 5675 } else { |
| 5675 statement = ParseExpr(kAllowConst); | 5676 statement = ParseExpr(kAllowConst); |
| 5676 ExpectSemicolon(); | 5677 ExpectSemicolon(); |
| 5677 } | 5678 } |
| 5678 return statement; | 5679 return statement; |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5947 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { | 5948 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { |
| 5948 ASSERT(type.IsMalformed()); | 5949 ASSERT(type.IsMalformed()); |
| 5949 ArgumentListNode* arguments = new ArgumentListNode(type_pos); | 5950 ArgumentListNode* arguments = new ArgumentListNode(type_pos); |
| 5950 // Location argument. | 5951 // Location argument. |
| 5951 arguments->Add(new LiteralNode( | 5952 arguments->Add(new LiteralNode( |
| 5952 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); | 5953 type_pos, Integer::ZoneHandle(Integer::New(type_pos)))); |
| 5953 // Src value argument. | 5954 // Src value argument. |
| 5954 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); | 5955 arguments->Add(new LiteralNode(type_pos, Instance::ZoneHandle())); |
| 5955 // Dst type name argument. | 5956 // Dst type name argument. |
| 5956 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 5957 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 5957 String::NewSymbol("malformed")))); | 5958 Symbols::New("malformed")))); |
| 5958 // Dst name argument. | 5959 // Dst name argument. |
| 5959 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 5960 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 5960 String::NewSymbol("")))); | 5961 Symbols::New("")))); |
| 5961 // Malformed type error. | 5962 // Malformed type error. |
| 5962 const Error& error = Error::Handle(type.malformed_error()); | 5963 const Error& error = Error::Handle(type.malformed_error()); |
| 5963 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 5964 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 5964 String::NewSymbol(error.ToErrorCString())))); | 5965 Symbols::New(error.ToErrorCString())))); |
| 5965 return MakeStaticCall(kTypeErrorName, kThrowNewName, arguments); | 5966 return MakeStaticCall(kTypeErrorName, kThrowNewName, arguments); |
| 5966 } | 5967 } |
| 5967 | 5968 |
| 5968 | 5969 |
| 5969 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 5970 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
| 5970 TRACE_PARSER("ParseBinaryExpr"); | 5971 TRACE_PARSER("ParseBinaryExpr"); |
| 5971 ASSERT(min_preced >= 4); | 5972 ASSERT(min_preced >= 4); |
| 5972 AstNode* left_operand = ParseUnaryExpr(); | 5973 AstNode* left_operand = ParseUnaryExpr(); |
| 5973 if (IsLiteral("as")) { // Not a reserved word. | 5974 if (IsLiteral("as")) { // Not a reserved word. |
| 5974 token_kind_ = Token::kAS; | 5975 token_kind_ = Token::kAS; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6074 } | 6075 } |
| 6075 | 6076 |
| 6076 | 6077 |
| 6077 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 6078 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
| 6078 intptr_t token_id, | 6079 intptr_t token_id, |
| 6079 const char* s) { | 6080 const char* s) { |
| 6080 char name[64]; | 6081 char name[64]; |
| 6081 OS::SNPrint(name, 64, ":%s%d", s, token_id); | 6082 OS::SNPrint(name, 64, ":%s%d", s, token_id); |
| 6082 LocalVariable* temp = | 6083 LocalVariable* temp = |
| 6083 new LocalVariable(token_pos, | 6084 new LocalVariable(token_pos, |
| 6084 String::ZoneHandle(String::NewSymbol(name)), | 6085 String::ZoneHandle(Symbols::New(name)), |
| 6085 Type::ZoneHandle(Type::DynamicType())); | 6086 Type::ZoneHandle(Type::DynamicType())); |
| 6086 temp->set_is_final(); | 6087 temp->set_is_final(); |
| 6087 current_block_->scope->AddVariable(temp); | 6088 current_block_->scope->AddVariable(temp); |
| 6088 return temp; | 6089 return temp; |
| 6089 } | 6090 } |
| 6090 | 6091 |
| 6091 | 6092 |
| 6092 // TODO(srdjan): Implement other optimizations. | 6093 // TODO(srdjan): Implement other optimizations. |
| 6093 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, | 6094 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, |
| 6094 Token::Kind binary_op, | 6095 Token::Kind binary_op, |
| (...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7513 } | 7514 } |
| 7514 } | 7515 } |
| 7515 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); | 7516 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); |
| 7516 | 7517 |
| 7517 // Parse the list elements. Note: there may be an optional extra | 7518 // Parse the list elements. Note: there may be an optional extra |
| 7518 // comma after the last element. | 7519 // comma after the last element. |
| 7519 ArrayNode* list = new ArrayNode(TokenPos(), type_arguments); | 7520 ArrayNode* list = new ArrayNode(TokenPos(), type_arguments); |
| 7520 if (!is_empty_literal) { | 7521 if (!is_empty_literal) { |
| 7521 const bool saved_mode = SetAllowFunctionLiterals(true); | 7522 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7522 const String& dst_name = String::ZoneHandle( | 7523 const String& dst_name = String::ZoneHandle( |
| 7523 String::NewSymbol("list literal element")); | 7524 Symbols::New("list literal element")); |
| 7524 while (CurrentToken() != Token::kRBRACK) { | 7525 while (CurrentToken() != Token::kRBRACK) { |
| 7525 const intptr_t element_pos = TokenPos(); | 7526 const intptr_t element_pos = TokenPos(); |
| 7526 AstNode* element = ParseExpr(is_const); | 7527 AstNode* element = ParseExpr(is_const); |
| 7527 if (FLAG_enable_type_checks && | 7528 if (FLAG_enable_type_checks && |
| 7528 !is_const && | 7529 !is_const && |
| 7529 !element_type.IsDynamicType()) { | 7530 !element_type.IsDynamicType()) { |
| 7530 element = new AssignableNode(element_pos, | 7531 element = new AssignableNode(element_pos, |
| 7531 element, | 7532 element, |
| 7532 element_type, | 7533 element_type, |
| 7533 dst_name); | 7534 dst_name); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7571 } | 7572 } |
| 7572 } | 7573 } |
| 7573 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 7574 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 7574 } | 7575 } |
| 7575 const_list ^= const_list.Canonicalize(); | 7576 const_list ^= const_list.Canonicalize(); |
| 7576 const_list.MakeImmutable(); | 7577 const_list.MakeImmutable(); |
| 7577 return new LiteralNode(literal_pos, const_list); | 7578 return new LiteralNode(literal_pos, const_list); |
| 7578 } else { | 7579 } else { |
| 7579 // Factory call at runtime. | 7580 // Factory call at runtime. |
| 7580 String& list_literal_factory_class_name = String::Handle( | 7581 String& list_literal_factory_class_name = String::Handle( |
| 7581 String::NewSymbol(kListLiteralFactoryClassName)); | 7582 Symbols::New(kListLiteralFactoryClassName)); |
| 7582 const Class& list_literal_factory_class = | 7583 const Class& list_literal_factory_class = |
| 7583 Class::Handle(LookupCoreClass(list_literal_factory_class_name)); | 7584 Class::Handle(LookupCoreClass(list_literal_factory_class_name)); |
| 7584 ASSERT(!list_literal_factory_class.IsNull()); | 7585 ASSERT(!list_literal_factory_class.IsNull()); |
| 7585 const String& list_literal_factory_name = | 7586 const String& list_literal_factory_name = |
| 7586 String::Handle(String::NewSymbol(kListLiteralFactoryName)); | 7587 String::Handle(Symbols::New(kListLiteralFactoryName)); |
| 7587 const Function& list_literal_factory = Function::ZoneHandle( | 7588 const Function& list_literal_factory = Function::ZoneHandle( |
| 7588 list_literal_factory_class.LookupFactory(list_literal_factory_name)); | 7589 list_literal_factory_class.LookupFactory(list_literal_factory_name)); |
| 7589 ASSERT(!list_literal_factory.IsNull()); | 7590 ASSERT(!list_literal_factory.IsNull()); |
| 7590 if (!type_arguments.IsNull() && | 7591 if (!type_arguments.IsNull() && |
| 7591 !type_arguments.IsInstantiated() && | 7592 !type_arguments.IsInstantiated() && |
| 7592 (current_block_->scope->function_level() > 0)) { | 7593 (current_block_->scope->function_level() > 0)) { |
| 7593 // Make sure that the instantiator is captured. | 7594 // Make sure that the instantiator is captured. |
| 7594 CaptureReceiver(); | 7595 CaptureReceiver(); |
| 7595 } | 7596 } |
| 7596 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 7597 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7697 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 7698 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 7698 map_type_arguments ^= map_type_arguments.Canonicalize(); | 7699 map_type_arguments ^= map_type_arguments.Canonicalize(); |
| 7699 | 7700 |
| 7700 // Parse the map entries. Note: there may be an optional extra | 7701 // Parse the map entries. Note: there may be an optional extra |
| 7701 // comma after the last entry. | 7702 // comma after the last entry. |
| 7702 // The kv_pair array is temporary and of element type Dynamic. It is passed | 7703 // The kv_pair array is temporary and of element type Dynamic. It is passed |
| 7703 // to the factory to initialize a properly typed map. | 7704 // to the factory to initialize a properly typed map. |
| 7704 ArrayNode* kv_pairs = | 7705 ArrayNode* kv_pairs = |
| 7705 new ArrayNode(TokenPos(), TypeArguments::ZoneHandle()); | 7706 new ArrayNode(TokenPos(), TypeArguments::ZoneHandle()); |
| 7706 const String& dst_name = String::ZoneHandle( | 7707 const String& dst_name = String::ZoneHandle( |
| 7707 String::NewSymbol("list literal element")); | 7708 Symbols::New("list literal element")); |
| 7708 while (CurrentToken() != Token::kRBRACE) { | 7709 while (CurrentToken() != Token::kRBRACE) { |
| 7709 AstNode* key = NULL; | 7710 AstNode* key = NULL; |
| 7710 if (CurrentToken() == Token::kSTRING) { | 7711 if (CurrentToken() == Token::kSTRING) { |
| 7711 key = ParseStringLiteral(); | 7712 key = ParseStringLiteral(); |
| 7712 } | 7713 } |
| 7713 if (key == NULL) { | 7714 if (key == NULL) { |
| 7714 ErrorMsg("map entry key must be string literal"); | 7715 ErrorMsg("map entry key must be string literal"); |
| 7715 } else if (is_const && !key->IsLiteralNode()) { | 7716 } else if (is_const && !key->IsLiteralNode()) { |
| 7716 ErrorMsg("map entry key must be compile time constant string"); | 7717 ErrorMsg("map entry key must be compile time constant string"); |
| 7717 } | 7718 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7769 String::Handle(value_type.UserVisibleName()).ToCString()); | 7770 String::Handle(value_type.UserVisibleName()).ToCString()); |
| 7770 } | 7771 } |
| 7771 } | 7772 } |
| 7772 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 7773 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 7773 } | 7774 } |
| 7774 key_value_array ^= key_value_array.Canonicalize(); | 7775 key_value_array ^= key_value_array.Canonicalize(); |
| 7775 key_value_array.MakeImmutable(); | 7776 key_value_array.MakeImmutable(); |
| 7776 | 7777 |
| 7777 // Construct the map object. | 7778 // Construct the map object. |
| 7778 const String& immutable_map_class_name = | 7779 const String& immutable_map_class_name = |
| 7779 String::Handle(String::NewSymbol(kImmutableMapName)); | 7780 String::Handle(Symbols::New(kImmutableMapName)); |
| 7780 const Class& immutable_map_class = | 7781 const Class& immutable_map_class = |
| 7781 Class::Handle(LookupImplClass(immutable_map_class_name)); | 7782 Class::Handle(LookupImplClass(immutable_map_class_name)); |
| 7782 ASSERT(!immutable_map_class.IsNull()); | 7783 ASSERT(!immutable_map_class.IsNull()); |
| 7783 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); | 7784 ArgumentListNode* constr_args = new ArgumentListNode(TokenPos()); |
| 7784 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); | 7785 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); |
| 7785 const String& constr_name = | 7786 const String& constr_name = |
| 7786 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); | 7787 String::Handle(Symbols::New(kImmutableMapConstructorName)); |
| 7787 const Function& map_constr = Function::ZoneHandle( | 7788 const Function& map_constr = Function::ZoneHandle( |
| 7788 immutable_map_class.LookupConstructor(constr_name)); | 7789 immutable_map_class.LookupConstructor(constr_name)); |
| 7789 ASSERT(!map_constr.IsNull()); | 7790 ASSERT(!map_constr.IsNull()); |
| 7790 const Object& constructor_result = Object::Handle( | 7791 const Object& constructor_result = Object::Handle( |
| 7791 EvaluateConstConstructorCall(immutable_map_class, | 7792 EvaluateConstConstructorCall(immutable_map_class, |
| 7792 map_type_arguments, | 7793 map_type_arguments, |
| 7793 map_constr, | 7794 map_constr, |
| 7794 constr_args)); | 7795 constr_args)); |
| 7795 if (constructor_result.IsUnhandledException()) { | 7796 if (constructor_result.IsUnhandledException()) { |
| 7796 return GenerateRethrow(literal_pos, constructor_result); | 7797 return GenerateRethrow(literal_pos, constructor_result); |
| 7797 } else { | 7798 } else { |
| 7798 const Instance& const_instance = Instance::Cast(constructor_result); | 7799 const Instance& const_instance = Instance::Cast(constructor_result); |
| 7799 return new LiteralNode(literal_pos, | 7800 return new LiteralNode(literal_pos, |
| 7800 Instance::ZoneHandle(const_instance.raw())); | 7801 Instance::ZoneHandle(const_instance.raw())); |
| 7801 } | 7802 } |
| 7802 } else { | 7803 } else { |
| 7803 // Factory call at runtime. | 7804 // Factory call at runtime. |
| 7804 String& map_literal_factory_class_name = String::Handle( | 7805 String& map_literal_factory_class_name = String::Handle( |
| 7805 String::NewSymbol(kMapLiteralFactoryClassName)); | 7806 Symbols::New(kMapLiteralFactoryClassName)); |
| 7806 const Class& map_literal_factory_class = | 7807 const Class& map_literal_factory_class = |
| 7807 Class::Handle(LookupCoreClass(map_literal_factory_class_name)); | 7808 Class::Handle(LookupCoreClass(map_literal_factory_class_name)); |
| 7808 ASSERT(!map_literal_factory_class.IsNull()); | 7809 ASSERT(!map_literal_factory_class.IsNull()); |
| 7809 const String& map_literal_factory_name = | 7810 const String& map_literal_factory_name = |
| 7810 String::Handle(String::NewSymbol(kMapLiteralFactoryName)); | 7811 String::Handle(Symbols::New(kMapLiteralFactoryName)); |
| 7811 const Function& map_literal_factory = Function::ZoneHandle( | 7812 const Function& map_literal_factory = Function::ZoneHandle( |
| 7812 map_literal_factory_class.LookupFactory(map_literal_factory_name)); | 7813 map_literal_factory_class.LookupFactory(map_literal_factory_name)); |
| 7813 ASSERT(!map_literal_factory.IsNull()); | 7814 ASSERT(!map_literal_factory.IsNull()); |
| 7814 if (!map_type_arguments.IsNull() && | 7815 if (!map_type_arguments.IsNull() && |
| 7815 !map_type_arguments.IsInstantiated() && | 7816 !map_type_arguments.IsInstantiated() && |
| 7816 (current_block_->scope->function_level() > 0)) { | 7817 (current_block_->scope->function_level() > 0)) { |
| 7817 // Make sure that the instantiator is captured. | 7818 // Make sure that the instantiator is captured. |
| 7818 CaptureReceiver(); | 7819 CaptureReceiver(); |
| 7819 } | 7820 } |
| 7820 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 7821 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7856 return primary; | 7857 return primary; |
| 7857 } | 7858 } |
| 7858 | 7859 |
| 7859 | 7860 |
| 7860 static const String& BuildConstructorName(const String& type_class_name, | 7861 static const String& BuildConstructorName(const String& type_class_name, |
| 7861 const String* named_constructor) { | 7862 const String* named_constructor) { |
| 7862 // By convention, the static function implementing a named constructor 'C' | 7863 // By convention, the static function implementing a named constructor 'C' |
| 7863 // for class 'A' is labeled 'A.C', and the static function implementing the | 7864 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 7864 // unnamed constructor for class 'A' is labeled 'A.'. | 7865 // unnamed constructor for class 'A' is labeled 'A.'. |
| 7865 // This convention prevents users from explicitly calling constructors. | 7866 // This convention prevents users from explicitly calling constructors. |
| 7866 const String& period = String::Handle(String::NewSymbol(".")); | 7867 const String& period = String::Handle(Symbols::Dot()); |
| 7867 String& constructor_name = | 7868 String& constructor_name = |
| 7868 String::Handle(String::Concat(type_class_name, period)); | 7869 String::Handle(String::Concat(type_class_name, period)); |
| 7869 if (named_constructor != NULL) { | 7870 if (named_constructor != NULL) { |
| 7870 constructor_name = String::Concat(constructor_name, *named_constructor); | 7871 constructor_name = String::Concat(constructor_name, *named_constructor); |
| 7871 } | 7872 } |
| 7872 return constructor_name; | 7873 return constructor_name; |
| 7873 } | 7874 } |
| 7874 | 7875 |
| 7875 | 7876 |
| 7876 AstNode* Parser::ParseNewOperator() { | 7877 AstNode* Parser::ParseNewOperator() { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8101 // mode at runtime that it is within its declared bounds. | 8102 // mode at runtime that it is within its declared bounds. |
| 8102 new_object = CreateConstructorCallNode( | 8103 new_object = CreateConstructorCallNode( |
| 8103 new_pos, type_arguments, constructor, arguments); | 8104 new_pos, type_arguments, constructor, arguments); |
| 8104 } | 8105 } |
| 8105 return new_object; | 8106 return new_object; |
| 8106 } | 8107 } |
| 8107 | 8108 |
| 8108 | 8109 |
| 8109 String& Parser::Interpolate(ArrayNode* values) { | 8110 String& Parser::Interpolate(ArrayNode* values) { |
| 8110 const String& class_name = | 8111 const String& class_name = |
| 8111 String::Handle(String::NewSymbol(kStringClassName)); | 8112 String::Handle(Symbols::New(kStringClassName)); |
| 8112 const Class& cls = Class::Handle(LookupImplClass(class_name)); | 8113 const Class& cls = Class::Handle(LookupImplClass(class_name)); |
| 8113 ASSERT(!cls.IsNull()); | 8114 ASSERT(!cls.IsNull()); |
| 8114 const String& func_name = String::Handle(String::NewSymbol(kInterpolateName)); | 8115 const String& func_name = String::Handle(Symbols::New(kInterpolateName)); |
| 8115 const Function& func = | 8116 const Function& func = |
| 8116 Function::Handle(cls.LookupStaticFunction(func_name)); | 8117 Function::Handle(cls.LookupStaticFunction(func_name)); |
| 8117 ASSERT(!func.IsNull()); | 8118 ASSERT(!func.IsNull()); |
| 8118 | 8119 |
| 8119 // Build the array of literal values to interpolate. | 8120 // Build the array of literal values to interpolate. |
| 8120 const Array& value_arr = Array::Handle(Array::New(values->length())); | 8121 const Array& value_arr = Array::Handle(Array::New(values->length())); |
| 8121 for (int i = 0; i < values->length(); i++) { | 8122 for (int i = 0; i < values->length(); i++) { |
| 8122 ASSERT(values->ElementAt(i)->IsLiteralNode()); | 8123 ASSERT(values->ElementAt(i)->IsLiteralNode()); |
| 8123 value_arr.SetAt(i, values->ElementAt(i)->AsLiteralNode()->literal()); | 8124 value_arr.SetAt(i, values->ElementAt(i)->AsLiteralNode()->literal()); |
| 8124 } | 8125 } |
| 8125 | 8126 |
| 8126 // Build argument array to pass to the interpolation function. | 8127 // Build argument array to pass to the interpolation function. |
| 8127 GrowableArray<const Object*> interpolate_arg; | 8128 GrowableArray<const Object*> interpolate_arg; |
| 8128 interpolate_arg.Add(&value_arr); | 8129 interpolate_arg.Add(&value_arr); |
| 8129 const Array& kNoArgumentNames = Array::Handle(); | 8130 const Array& kNoArgumentNames = Array::Handle(); |
| 8130 | 8131 |
| 8131 // Call interpolation function. | 8132 // Call interpolation function. |
| 8132 String& concatenated = String::ZoneHandle(); | 8133 String& concatenated = String::ZoneHandle(); |
| 8133 concatenated ^= DartEntry::InvokeStatic(func, | 8134 concatenated ^= DartEntry::InvokeStatic(func, |
| 8134 interpolate_arg, | 8135 interpolate_arg, |
| 8135 kNoArgumentNames); | 8136 kNoArgumentNames); |
| 8136 if (concatenated.IsUnhandledException()) { | 8137 if (concatenated.IsUnhandledException()) { |
| 8137 ErrorMsg("Exception thrown in Parser::Interpolate"); | 8138 ErrorMsg("Exception thrown in Parser::Interpolate"); |
| 8138 } | 8139 } |
| 8139 concatenated = String::NewSymbol(concatenated); | 8140 concatenated = Symbols::New(concatenated); |
| 8140 return concatenated; | 8141 return concatenated; |
| 8141 } | 8142 } |
| 8142 | 8143 |
| 8143 | 8144 |
| 8144 // A string literal consists of the concatenation of the next n tokens | 8145 // A string literal consists of the concatenation of the next n tokens |
| 8145 // that satisfy the EBNF grammar: | 8146 // that satisfy the EBNF grammar: |
| 8146 // literal = kSTRING {{ interpol } kSTRING } | 8147 // literal = kSTRING {{ interpol } kSTRING } |
| 8147 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 8148 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 8148 // In other words, the scanner breaks down interpolated strings so that | 8149 // In other words, the scanner breaks down interpolated strings so that |
| 8149 // a string literal always begins and ends with a kSTRING token. | 8150 // a string literal always begins and ends with a kSTRING token. |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8305 } | 8306 } |
| 8306 } else { | 8307 } else { |
| 8307 // This is a qualified identifier with a library prefix so resolve | 8308 // This is a qualified identifier with a library prefix so resolve |
| 8308 // the identifier locally in that library (we do not include the | 8309 // the identifier locally in that library (we do not include the |
| 8309 // libraries imported by that library). | 8310 // libraries imported by that library). |
| 8310 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), | 8311 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), |
| 8311 qual_ident); | 8312 qual_ident); |
| 8312 } | 8313 } |
| 8313 ASSERT(primary != NULL); | 8314 ASSERT(primary != NULL); |
| 8314 } else if (CurrentToken() == Token::kTHIS) { | 8315 } else if (CurrentToken() == Token::kTHIS) { |
| 8315 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 8316 const String& this_name = String::Handle(Symbols::New(kThisName)); |
| 8316 LocalVariable* local = LookupLocalScope(this_name); | 8317 LocalVariable* local = LookupLocalScope(this_name); |
| 8317 if (local == NULL) { | 8318 if (local == NULL) { |
| 8318 ErrorMsg("receiver 'this' is not in scope"); | 8319 ErrorMsg("receiver 'this' is not in scope"); |
| 8319 } | 8320 } |
| 8320 primary = new LoadLocalNode(TokenPos(), *local); | 8321 primary = new LoadLocalNode(TokenPos(), *local); |
| 8321 ConsumeToken(); | 8322 ConsumeToken(); |
| 8322 } else if (CurrentToken() == Token::kINTEGER) { | 8323 } else if (CurrentToken() == Token::kINTEGER) { |
| 8323 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); | 8324 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); |
| 8324 primary = new LiteralNode(TokenPos(), literal); | 8325 primary = new LiteralNode(TokenPos(), literal); |
| 8325 ConsumeToken(); | 8326 ConsumeToken(); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8666 void Parser::SkipQualIdent() { | 8667 void Parser::SkipQualIdent() { |
| 8667 ASSERT(IsIdentifier()); | 8668 ASSERT(IsIdentifier()); |
| 8668 ConsumeToken(); | 8669 ConsumeToken(); |
| 8669 if (CurrentToken() == Token::kPERIOD) { | 8670 if (CurrentToken() == Token::kPERIOD) { |
| 8670 ConsumeToken(); // Consume the kPERIOD token. | 8671 ConsumeToken(); // Consume the kPERIOD token. |
| 8671 ExpectIdentifier("identifier expected after '.'"); | 8672 ExpectIdentifier("identifier expected after '.'"); |
| 8672 } | 8673 } |
| 8673 } | 8674 } |
| 8674 | 8675 |
| 8675 } // namespace dart | 8676 } // namespace dart |
| OLD | NEW |