| 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" |
| (...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 void Parser::CheckFunctionIsCallable(intptr_t token_pos, | 1249 void Parser::CheckFunctionIsCallable(intptr_t token_pos, |
| 1250 const Function& function) { | 1250 const Function& function) { |
| 1251 if (Class::Handle(function.Owner()).is_interface()) { | 1251 if (Class::Handle(function.Owner()).is_interface()) { |
| 1252 ErrorMsg(token_pos, "cannot call function of interface '%s'", | 1252 ErrorMsg(token_pos, "cannot call function of interface '%s'", |
| 1253 function.ToFullyQualifiedCString()); | 1253 function.ToFullyQualifiedCString()); |
| 1254 } | 1254 } |
| 1255 } | 1255 } |
| 1256 | 1256 |
| 1257 | 1257 |
| 1258 // Resolve and return the dynamic function of the given name in the superclass. | 1258 // Resolve and return the dynamic function of the given name in the superclass. |
| 1259 // If it is not found, return noSuchMethod and set is_no_such_method to true. | 1259 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1260 // the same name. If it is still not found, return noSuchMethod and |
| 1261 // set is_no_such_method to true.. |
| 1260 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1262 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1261 const String& name, | 1263 const String& name, |
| 1264 bool resolve_getter, |
| 1262 bool* is_no_such_method) { | 1265 bool* is_no_such_method) { |
| 1263 const Class& super_class = Class::Handle(current_class().SuperClass()); | 1266 const Class& super_class = Class::Handle(current_class().SuperClass()); |
| 1264 if (super_class.IsNull()) { | 1267 if (super_class.IsNull()) { |
| 1265 ErrorMsg(token_pos, "class '%s' does not have a superclass", | 1268 ErrorMsg(token_pos, "class '%s' does not have a superclass", |
| 1266 String::Handle(current_class().Name()).ToCString()); | 1269 String::Handle(current_class().Name()).ToCString()); |
| 1267 } | 1270 } |
| 1268 | |
| 1269 Function& super_func = | 1271 Function& super_func = |
| 1270 Function::Handle(Resolver::ResolveDynamicAnyArgs(super_class, name)); | 1272 Function::Handle(Resolver::ResolveDynamicAnyArgs(super_class, name)); |
| 1273 if (super_func.IsNull() && resolve_getter) { |
| 1274 const String& getter_name = String::ZoneHandle(Field::GetterName(name)); |
| 1275 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); |
| 1276 ASSERT(super_func.IsNull() || |
| 1277 (super_func.kind() != RawFunction::kConstImplicitGetter)); |
| 1278 } |
| 1271 if (super_func.IsNull()) { | 1279 if (super_func.IsNull()) { |
| 1272 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); | 1280 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); |
| 1273 super_func = | 1281 super_func = |
| 1274 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name); | 1282 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name); |
| 1275 ASSERT(!super_func.IsNull()); | 1283 ASSERT(!super_func.IsNull()); |
| 1276 *is_no_such_method = true; | 1284 *is_no_such_method = true; |
| 1277 } else { | 1285 } else { |
| 1278 *is_no_such_method = false; | 1286 *is_no_such_method = false; |
| 1279 } | 1287 } |
| 1280 CheckFunctionIsCallable(token_pos, super_func); | 1288 CheckFunctionIsCallable(token_pos, super_func); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 arguments->Add(args_array); | 1331 arguments->Add(args_array); |
| 1324 return arguments; | 1332 return arguments; |
| 1325 } | 1333 } |
| 1326 | 1334 |
| 1327 | 1335 |
| 1328 AstNode* Parser::ParseSuperCall(const String& function_name) { | 1336 AstNode* Parser::ParseSuperCall(const String& function_name) { |
| 1329 TRACE_PARSER("ParseSuperCall"); | 1337 TRACE_PARSER("ParseSuperCall"); |
| 1330 ASSERT(CurrentToken() == Token::kLPAREN); | 1338 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1331 const intptr_t supercall_pos = TokenPos(); | 1339 const intptr_t supercall_pos = TokenPos(); |
| 1332 | 1340 |
| 1341 const bool kResolveGetter = true; |
| 1333 bool is_no_such_method = false; | 1342 bool is_no_such_method = false; |
| 1334 const Function& super_function = Function::ZoneHandle( | 1343 const Function& super_function = Function::ZoneHandle( |
| 1335 GetSuperFunction(supercall_pos, function_name, &is_no_such_method)); | 1344 GetSuperFunction(supercall_pos, |
| 1336 | 1345 function_name, |
| 1346 kResolveGetter, |
| 1347 &is_no_such_method)); |
| 1337 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1348 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1349 if (super_function.IsGetterFunction() || |
| 1350 super_function.IsImplicitGetterFunction()) { |
| 1351 // 'this' is not passed as parameter to the closure. |
| 1352 ParseActualParameters(arguments, kAllowConst); |
| 1353 const Class& super_class = Class::ZoneHandle(current_class().SuperClass()); |
| 1354 AstNode* closure = new StaticGetterNode(supercall_pos, |
| 1355 LoadReceiver(supercall_pos), |
| 1356 /* is_super_getter */ true, |
| 1357 super_class, |
| 1358 function_name); |
| 1359 EnsureExpressionTemp(); |
| 1360 return new ClosureCallNode(supercall_pos, closure, arguments); |
| 1361 } |
| 1338 // 'this' parameter is the first argument to super call. | 1362 // 'this' parameter is the first argument to super call. |
| 1339 AstNode* receiver = LoadReceiver(supercall_pos); | 1363 AstNode* receiver = LoadReceiver(supercall_pos); |
| 1340 arguments->Add(receiver); | 1364 arguments->Add(receiver); |
| 1341 ParseActualParameters(arguments, kAllowConst); | 1365 ParseActualParameters(arguments, kAllowConst); |
| 1342 if (is_no_such_method) { | 1366 if (is_no_such_method) { |
| 1343 arguments = BuildNoSuchMethodArguments(function_name, *arguments); | 1367 arguments = BuildNoSuchMethodArguments(function_name, *arguments); |
| 1344 } | 1368 } |
| 1345 return new StaticCallNode(supercall_pos, super_function, arguments); | 1369 return new StaticCallNode(supercall_pos, super_function, arguments); |
| 1346 } | 1370 } |
| 1347 | 1371 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1378 CreateTempConstVariable(operator_pos, "lix"); | 1402 CreateTempConstVariable(operator_pos, "lix"); |
| 1379 AstNode* save = new StoreLocalNode(operator_pos, temp, index_expr); | 1403 AstNode* save = new StoreLocalNode(operator_pos, temp, index_expr); |
| 1380 current_block_->statements->Add(save); | 1404 current_block_->statements->Add(save); |
| 1381 index_expr = new LoadLocalNode(operator_pos, temp); | 1405 index_expr = new LoadLocalNode(operator_pos, temp); |
| 1382 } | 1406 } |
| 1383 } | 1407 } |
| 1384 | 1408 |
| 1385 // Resolve the [] operator function in the superclass. | 1409 // Resolve the [] operator function in the superclass. |
| 1386 const String& index_operator_name = | 1410 const String& index_operator_name = |
| 1387 String::ZoneHandle(Symbols::IndexToken()); | 1411 String::ZoneHandle(Symbols::IndexToken()); |
| 1412 const bool kResolveGetter = false; |
| 1388 bool is_no_such_method = false; | 1413 bool is_no_such_method = false; |
| 1389 const Function& index_operator = Function::ZoneHandle( | 1414 const Function& index_operator = Function::ZoneHandle( |
| 1390 GetSuperFunction(operator_pos, | 1415 GetSuperFunction(operator_pos, |
| 1391 index_operator_name, | 1416 index_operator_name, |
| 1417 kResolveGetter, |
| 1392 &is_no_such_method)); | 1418 &is_no_such_method)); |
| 1393 | 1419 |
| 1394 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos); | 1420 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos); |
| 1395 AstNode* receiver = LoadReceiver(operator_pos); | 1421 AstNode* receiver = LoadReceiver(operator_pos); |
| 1396 index_op_arguments->Add(receiver); | 1422 index_op_arguments->Add(receiver); |
| 1397 index_op_arguments->Add(index_expr); | 1423 index_op_arguments->Add(index_expr); |
| 1398 | 1424 |
| 1399 if (is_no_such_method) { | 1425 if (is_no_such_method) { |
| 1400 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name, | 1426 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name, |
| 1401 *index_op_arguments); | 1427 *index_op_arguments); |
| 1402 } | 1428 } |
| 1403 super_op = new StaticCallNode( | 1429 super_op = new StaticCallNode( |
| 1404 operator_pos, index_operator, index_op_arguments); | 1430 operator_pos, index_operator, index_op_arguments); |
| 1405 | 1431 |
| 1406 if (Token::IsAssignmentOperator(CurrentToken())) { | 1432 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 1407 Token::Kind assignment_op = CurrentToken(); | 1433 Token::Kind assignment_op = CurrentToken(); |
| 1408 ConsumeToken(); | 1434 ConsumeToken(); |
| 1409 AstNode* value = ParseExpr(kAllowConst, kConsumeCascades); | 1435 AstNode* value = ParseExpr(kAllowConst, kConsumeCascades); |
| 1410 | 1436 |
| 1411 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); | 1437 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); |
| 1412 | 1438 |
| 1413 // Resolve the []= operator function in the superclass. | 1439 // Resolve the []= operator function in the superclass. |
| 1414 const String& assign_index_operator_name = | 1440 const String& assign_index_operator_name = |
| 1415 String::ZoneHandle(Symbols::AssignIndexToken()); | 1441 String::ZoneHandle(Symbols::AssignIndexToken()); |
| 1442 const bool kResolveGetter = false; |
| 1416 bool is_no_such_method = false; | 1443 bool is_no_such_method = false; |
| 1417 const Function& assign_index_operator = Function::ZoneHandle( | 1444 const Function& assign_index_operator = Function::ZoneHandle( |
| 1418 GetSuperFunction(operator_pos, | 1445 GetSuperFunction(operator_pos, |
| 1419 assign_index_operator_name, | 1446 assign_index_operator_name, |
| 1447 kResolveGetter, |
| 1420 &is_no_such_method)); | 1448 &is_no_such_method)); |
| 1421 | 1449 |
| 1422 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos); | 1450 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos); |
| 1423 operator_args->Add(LoadReceiver(operator_pos)); | 1451 operator_args->Add(LoadReceiver(operator_pos)); |
| 1424 operator_args->Add(index_expr); | 1452 operator_args->Add(index_expr); |
| 1425 operator_args->Add(value); | 1453 operator_args->Add(value); |
| 1426 | 1454 |
| 1427 if (is_no_such_method) { | 1455 if (is_no_such_method) { |
| 1428 operator_args = BuildNoSuchMethodArguments(assign_index_operator_name, | 1456 operator_args = BuildNoSuchMethodArguments(assign_index_operator_name, |
| 1429 *operator_args); | 1457 *operator_args); |
| 1430 } | 1458 } |
| 1431 super_op = new StaticCallNode( | 1459 super_op = new StaticCallNode( |
| 1432 operator_pos, assign_index_operator, operator_args); | 1460 operator_pos, assign_index_operator, operator_args); |
| 1433 } | 1461 } |
| 1434 } else if (Token::CanBeOverloaded(CurrentToken())) { | 1462 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 1435 Token::Kind op = CurrentToken(); | 1463 Token::Kind op = CurrentToken(); |
| 1436 ConsumeToken(); | 1464 ConsumeToken(); |
| 1437 | 1465 |
| 1438 // Resolve the operator function in the superclass. | 1466 // Resolve the operator function in the superclass. |
| 1439 const String& operator_function_name = | 1467 const String& operator_function_name = |
| 1440 String::Handle(Symbols::New(Token::Str(op))); | 1468 String::Handle(Symbols::New(Token::Str(op))); |
| 1469 const bool kResolveGetter = false; |
| 1441 bool is_no_such_method = false; | 1470 bool is_no_such_method = false; |
| 1442 const Function& super_operator = Function::ZoneHandle( | 1471 const Function& super_operator = Function::ZoneHandle( |
| 1443 GetSuperFunction(operator_pos, | 1472 GetSuperFunction(operator_pos, |
| 1444 operator_function_name, | 1473 operator_function_name, |
| 1474 kResolveGetter, |
| 1445 &is_no_such_method)); | 1475 &is_no_such_method)); |
| 1446 | 1476 |
| 1447 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); | 1477 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); |
| 1448 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); | 1478 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); |
| 1449 | 1479 |
| 1450 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); | 1480 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); |
| 1451 AstNode* receiver = LoadReceiver(operator_pos); | 1481 AstNode* receiver = LoadReceiver(operator_pos); |
| 1452 op_arguments->Add(receiver); | 1482 op_arguments->Add(receiver); |
| 1453 op_arguments->Add(other_operand); | 1483 op_arguments->Add(other_operand); |
| 1454 | 1484 |
| (...skipping 3231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4686 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope, | 4716 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope, |
| 4687 kTestOnly); | 4717 kTestOnly); |
| 4688 ASSERT(param != NULL); | 4718 ASSERT(param != NULL); |
| 4689 return new LoadLocalNode(TokenPos(), param); | 4719 return new LoadLocalNode(TokenPos(), param); |
| 4690 } | 4720 } |
| 4691 | 4721 |
| 4692 | 4722 |
| 4693 AstNode* Parser::CallGetter(intptr_t token_pos, | 4723 AstNode* Parser::CallGetter(intptr_t token_pos, |
| 4694 AstNode* object, | 4724 AstNode* object, |
| 4695 const String& name) { | 4725 const String& name) { |
| 4696 return new InstanceGetterNode(TokenPos(), object, name); | 4726 return new InstanceGetterNode(token_pos, object, name); |
| 4697 } | 4727 } |
| 4698 | 4728 |
| 4699 | 4729 |
| 4700 // Returns ast nodes of the variable initialization. | 4730 // Returns ast nodes of the variable initialization. |
| 4701 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 4731 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 4702 bool is_final, | 4732 bool is_final, |
| 4703 bool is_const) { | 4733 bool is_const) { |
| 4704 TRACE_PARSER("ParseVariableDeclaration"); | 4734 TRACE_PARSER("ParseVariableDeclaration"); |
| 4705 ASSERT(IsIdentifier()); | 4735 ASSERT(IsIdentifier()); |
| 4706 const intptr_t ident_pos = TokenPos(); | 4736 const intptr_t ident_pos = TokenPos(); |
| (...skipping 4985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9692 void Parser::SkipQualIdent() { | 9722 void Parser::SkipQualIdent() { |
| 9693 ASSERT(IsIdentifier()); | 9723 ASSERT(IsIdentifier()); |
| 9694 ConsumeToken(); | 9724 ConsumeToken(); |
| 9695 if (CurrentToken() == Token::kPERIOD) { | 9725 if (CurrentToken() == Token::kPERIOD) { |
| 9696 ConsumeToken(); // Consume the kPERIOD token. | 9726 ConsumeToken(); // Consume the kPERIOD token. |
| 9697 ExpectIdentifier("identifier expected after '.'"); | 9727 ExpectIdentifier("identifier expected after '.'"); |
| 9698 } | 9728 } |
| 9699 } | 9729 } |
| 9700 | 9730 |
| 9701 } // namespace dart | 9731 } // namespace dart |
| OLD | NEW |