Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: runtime/vm/parser.cc

Issue 11088014: Look up getter in super call (issue 3621). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698