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

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

Issue 8440014: Two-phase constructors (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month 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/language/language.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 23 matching lines...) Expand all
34 static const char* kGrowableObjectArrayFromArrayName = 34 static const char* kGrowableObjectArrayFromArrayName =
35 "GrowableObjectArray._usingArray"; 35 "GrowableObjectArray._usingArray";
36 static const char* kGrowableObjectArrayName = "GrowableObjectArray"; 36 static const char* kGrowableObjectArrayName = "GrowableObjectArray";
37 static const char* kMutableMapName = "MutableMap"; 37 static const char* kMutableMapName = "MutableMap";
38 static const char* kMutableMapFromLiteralName = "fromLiteral"; 38 static const char* kMutableMapFromLiteralName = "fromLiteral";
39 static const char* kImmutableMapName = "ImmutableMap"; 39 static const char* kImmutableMapName = "ImmutableMap";
40 static const char* kImmutableMapConstructorName = "ImmutableMap."; 40 static const char* kImmutableMapConstructorName = "ImmutableMap.";
41 static const char* kStringClassName = "StringBase"; 41 static const char* kStringClassName = "StringBase";
42 static const char* kInterpolateName = "_interpolate"; 42 static const char* kInterpolateName = "_interpolate";
43 static const char* kThisName = "this"; 43 static const char* kThisName = "this";
44 static const char* kPhaseParameterName = ":phase";
44 static const char* kGetIteratorName = "iterator"; 45 static const char* kGetIteratorName = "iterator";
45 46
46 #if defined(DEBUG) 47 #if defined(DEBUG)
47 48
48 class TraceParser : public ValueObject { 49 class TraceParser : public ValueObject {
49 public: 50 public:
50 TraceParser(intptr_t token_index, const Script& script, const char* msg) { 51 TraceParser(intptr_t token_index, const Script& script, const char* msg) {
51 if (FLAG_trace_parser) { 52 if (FLAG_trace_parser) {
52 intptr_t line, column; 53 intptr_t line, column;
53 script.GetTokenLocation(token_index, &line, &column); 54 script.GetTokenLocation(token_index, &line, &column);
(...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 1031
1031 1032
1032 AstNode* Parser::ParseSuperCall(const String& function_name) { 1033 AstNode* Parser::ParseSuperCall(const String& function_name) {
1033 TRACE_PARSER("ParseSuperCall"); 1034 TRACE_PARSER("ParseSuperCall");
1034 ASSERT(CurrentToken() == Token::kLPAREN); 1035 ASSERT(CurrentToken() == Token::kLPAREN);
1035 const intptr_t supercall_pos = token_index_; 1036 const intptr_t supercall_pos = token_index_;
1036 1037
1037 const Function& super_function = Function::ZoneHandle( 1038 const Function& super_function = Function::ZoneHandle(
1038 GetSuperFunction(supercall_pos, function_name)); 1039 GetSuperFunction(supercall_pos, function_name));
1039 1040
1041 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1040 // 'this' parameter is the first argument to super call. 1042 // 'this' parameter is the first argument to super call.
1041 AstNode* receiver = LoadReceiver(supercall_pos); 1043 AstNode* receiver = LoadReceiver(supercall_pos);
1042 ArgumentListNode* arguments = 1044 arguments->Add(receiver);
1043 ParseActualParameters(receiver, kAllowConst); 1045 ParseActualParameters(arguments, kAllowConst);
1044 return new StaticCallNode(supercall_pos, super_function, arguments); 1046 return new StaticCallNode(supercall_pos, super_function, arguments);
1045 } 1047 }
1046 1048
1047 1049
1048 AstNode* Parser::ParseSuperOperator() { 1050 AstNode* Parser::ParseSuperOperator() {
1049 TRACE_PARSER("ParseSuperOperator"); 1051 TRACE_PARSER("ParseSuperOperator");
1050 AstNode* super_op = NULL; 1052 AstNode* super_op = NULL;
1051 const intptr_t operator_pos = token_index_; 1053 const intptr_t operator_pos = token_index_;
1052 1054
1053 if (CurrentToken() == Token::kLBRACK) { 1055 if (CurrentToken() == Token::kLBRACK) {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 1207
1206 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos); 1208 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos);
1207 setter_arguments->Add(implicit_argument); 1209 setter_arguments->Add(implicit_argument);
1208 setter_arguments->Add(value); 1210 setter_arguments->Add(value);
1209 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); 1211 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments);
1210 } 1212 }
1211 return super_field; 1213 return super_field;
1212 } 1214 }
1213 1215
1214 1216
1215 void Parser::GenerateSuperInitializerCall(const Class& cls, 1217 void Parser::GenerateSuperConstructorCall(const Class& cls,
1216 LocalVariable* receiver) { 1218 LocalVariable* receiver) {
1217 const intptr_t supercall_pos = token_index_; 1219 const intptr_t supercall_pos = token_index_;
1218 const Class& super_class = Class::Handle(cls.SuperClass()); 1220 const Class& super_class = Class::Handle(cls.SuperClass());
1219 // Omit the implicit super() if there is no super class (i.e. 1221 // Omit the implicit super() if there is no super class (i.e.
1220 // we're not compiling class Object), or if the super class is an 1222 // we're not compiling class Object), or if the super class is an
1221 // artificially generated "wrapper class" that has no constructor. 1223 // artificially generated "wrapper class" that has no constructor.
1222 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { 1224 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) {
1223 return; 1225 return;
1224 } 1226 }
1225 String& ctor_name = String::Handle(super_class.Name()); 1227 String& ctor_name = String::Handle(super_class.Name());
1226 String& ctor_suffix = String::Handle(String::NewSymbol(".")); 1228 String& ctor_suffix = String::Handle(String::NewSymbol("."));
1227 ctor_name = String::Concat(ctor_name, ctor_suffix); 1229 ctor_name = String::Concat(ctor_name, ctor_suffix);
1228 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); 1230 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1229 // implicit 'this' parameter is the only argument. 1231 // Implicit 'this' parameter is the first argument.
1230 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); 1232 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver);
1231 arguments->Add(implicit_argument); 1233 arguments->Add(implicit_argument);
1234 // Implicit constructor phase parameter is second argument.
1235 AstNode* phase_parameter =
1236 new LiteralNode(supercall_pos,
1237 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
1238 arguments->Add(phase_parameter);
1232 const Function& super_ctor = Function::ZoneHandle( 1239 const Function& super_ctor = Function::ZoneHandle(
1233 super_class.LookupConstructor(ctor_name)); 1240 super_class.LookupConstructor(ctor_name));
1234 if (super_ctor.IsNull() || 1241 if (super_ctor.IsNull() ||
1235 !super_ctor.AreValidArguments(arguments->length(), 1242 !super_ctor.AreValidArguments(arguments->length(),
1236 arguments->names())) { 1243 arguments->names())) {
1237 ErrorMsg(supercall_pos, 1244 ErrorMsg(supercall_pos,
1238 "unresolved implicit call to super constructor '%s()'", 1245 "unresolved implicit call to super constructor '%s()'",
1239 String::Handle(super_class.Name()).ToCString()); 1246 String::Handle(super_class.Name()).ToCString());
1240 } 1247 }
1241 CheckFunctionIsCallable(supercall_pos, super_ctor); 1248 CheckFunctionIsCallable(supercall_pos, super_ctor);
(...skipping 14 matching lines...) Expand all
1256 String& ctor_suffix = String::Handle(String::NewSymbol(".")); 1263 String& ctor_suffix = String::Handle(String::NewSymbol("."));
1257 if (CurrentToken() == Token::kPERIOD) { 1264 if (CurrentToken() == Token::kPERIOD) {
1258 ConsumeToken(); 1265 ConsumeToken();
1259 ctor_suffix = String::Concat( 1266 ctor_suffix = String::Concat(
1260 ctor_suffix, *ExpectIdentifier("constructor name expected")); 1267 ctor_suffix, *ExpectIdentifier("constructor name expected"));
1261 } 1268 }
1262 ctor_name = String::Concat(ctor_name, ctor_suffix); 1269 ctor_name = String::Concat(ctor_name, ctor_suffix);
1263 if (CurrentToken() != Token::kLPAREN) { 1270 if (CurrentToken() != Token::kLPAREN) {
1264 ErrorMsg("parameter list expected"); 1271 ErrorMsg("parameter list expected");
1265 } 1272 }
1273
1274 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1266 // 'this' parameter is the first argument to super class constructor. 1275 // 'this' parameter is the first argument to super class constructor.
1267 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); 1276 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver);
1277 arguments->Add(implicit_argument);
1278 // Second implicit parameter is the constructor phase. We optimistically
1279 // assume that we can execute both the super initializer and the super
1280 // constructor body. We may later change this to only execute the
1281 // super initializer.
1282 AstNode* phase_parameter =
1283 new LiteralNode(supercall_pos,
1284 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
1285 arguments->Add(phase_parameter);
1268 // 'this' parameter must not be accessible to the other super call arguments. 1286 // 'this' parameter must not be accessible to the other super call arguments.
1269 receiver->set_invisible(true); 1287 receiver->set_invisible(true);
1270 ArgumentListNode* arguments = 1288 ParseActualParameters(arguments, kAllowConst);
1271 ParseActualParameters(implicit_argument, kAllowConst);
1272 receiver->set_invisible(false); 1289 receiver->set_invisible(false);
1290
1273 // Resolve the constructor. 1291 // Resolve the constructor.
1274 const Function& super_ctor = Function::ZoneHandle( 1292 const Function& super_ctor = Function::ZoneHandle(
1275 super_class.LookupConstructor(ctor_name)); 1293 super_class.LookupConstructor(ctor_name));
1276 if (super_ctor.IsNull() || 1294 if (super_ctor.IsNull() ||
1277 !super_ctor.AreValidArguments(arguments->length(), 1295 !super_ctor.AreValidArguments(arguments->length(),
1278 arguments->names())) { 1296 arguments->names())) {
1279 ErrorMsg(supercall_pos, 1297 ErrorMsg(supercall_pos,
1280 "super class constructor '%s' not found", 1298 "super class constructor '%s' not found",
1281 ctor_name.ToCString()); 1299 ctor_name.ToCString());
1282 } 1300 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 FieldInitExpression initializer; 1384 FieldInitExpression initializer;
1367 initializer.inst_field = &field; 1385 initializer.inst_field = &field;
1368 initializer.expr = init_expr; 1386 initializer.expr = init_expr;
1369 initializers->Add(initializer); 1387 initializers->Add(initializer);
1370 } 1388 }
1371 } 1389 }
1372 SetPosition(saved_pos); 1390 SetPosition(saved_pos);
1373 } 1391 }
1374 1392
1375 1393
1376 void Parser::ParseInitializers(const Class& cls) { 1394 void Parser::ParseInitializers(const Class& cls, LocalVariable* receiver) {
1377 TRACE_PARSER("ParseInitializers"); 1395 TRACE_PARSER("ParseInitializers");
1378 LocalVariable* receiver = current_block_->scope->VariableAt(0); 1396 bool super_init_seen = false;
1379 AstNode* super_init_statement = NULL;
1380 if (CurrentToken() == Token::kCOLON) { 1397 if (CurrentToken() == Token::kCOLON) {
1381 if ((LookaheadToken(1) == Token::kTHIS) && 1398 if ((LookaheadToken(1) == Token::kTHIS) &&
1382 ((LookaheadToken(2) == Token::kLPAREN) || 1399 ((LookaheadToken(2) == Token::kLPAREN) ||
1383 ((LookaheadToken(2) == Token::kPERIOD) && 1400 ((LookaheadToken(2) == Token::kPERIOD) &&
1384 (LookaheadToken(4) == Token::kLPAREN)))) { 1401 (LookaheadToken(4) == Token::kLPAREN)))) {
1385 // Either we see this(...) or this.xxx(...) which is a 1402 // Either we see this(...) or this.xxx(...) which is a
1386 // redirected constructor. We don't need to check whether 1403 // redirected constructor. We don't need to check whether
1387 // const fields are initialized. The other constructor will 1404 // const fields are initialized. The other constructor will
1388 // guarantee that. 1405 // guarantee that.
1389 ConsumeToken(); // Colon. 1406 ConsumeToken(); // Colon.
1390 ParseConstructorRedirection(cls, receiver); 1407 ParseConstructorRedirection(cls, receiver);
1391 return; 1408 return;
1392 } 1409 }
1393
1394 do { 1410 do {
1395 ConsumeToken(); // Colon or comma. 1411 ConsumeToken(); // Colon or comma.
1412 AstNode* init_statement;
1396 if (CurrentToken() == Token::kSUPER) { 1413 if (CurrentToken() == Token::kSUPER) {
1397 if (super_init_statement != NULL) { 1414 if (super_init_seen) {
1398 ErrorMsg("Duplicate call to super constructor"); 1415 ErrorMsg("Duplicate call to super constructor");
1399 } 1416 }
1400 super_init_statement = ParseSuperInitializer(cls, receiver); 1417 init_statement = ParseSuperInitializer(cls, receiver);
1418 super_init_seen = true;
1401 } else { 1419 } else {
1402 AstNode* init_statement = ParseInitializer(cls, receiver); 1420 init_statement = ParseInitializer(cls, receiver);
1403 current_block_->statements->Add(init_statement);
1404 } 1421 }
1422 current_block_->statements->Add(init_statement);
1405 } while (CurrentToken() == Token::kCOMMA); 1423 } while (CurrentToken() == Token::kCOMMA);
1406 } 1424 }
1407 1425 if (!super_init_seen) {
1408 if (super_init_statement != NULL) {
1409 // Move explicit supercall to the end of the initializer list to
1410 // avoid executing constructor code on partially initialized objects.
1411 // TODO(hausner): Fix issue 4995181, evaluation order of constructor
1412 // initializer lists.
1413 current_block_->statements->Add(super_init_statement);
1414 } else {
1415 // Generate implicit super() if we haven't seen an explicit super call 1426 // Generate implicit super() if we haven't seen an explicit super call
1416 // or constructor redirection. 1427 // or constructor redirection.
1417 GenerateSuperInitializerCall(cls, receiver); 1428 GenerateSuperConstructorCall(cls, receiver);
1418 } 1429 }
1419
1420 CheckConstFieldsInitialized(cls); 1430 CheckConstFieldsInitialized(cls);
1421 } 1431 }
1422 1432
1423 1433
1424 void Parser::ParseConstructorRedirection(const Class& cls, 1434 void Parser::ParseConstructorRedirection(const Class& cls,
1425 LocalVariable* receiver) { 1435 LocalVariable* receiver) {
1426 ASSERT(CurrentToken() == Token::kTHIS); 1436 ASSERT(CurrentToken() == Token::kTHIS);
1427 intptr_t call_pos = token_index_; 1437 intptr_t call_pos = token_index_;
1428 ConsumeToken(); 1438 ConsumeToken();
1429 String& ctor_name = String::Handle(cls.Name()); 1439 String& ctor_name = String::Handle(cls.Name());
1430 String& ctor_suffix = String::Handle(String::NewSymbol(".")); 1440 String& ctor_suffix = String::Handle(String::NewSymbol("."));
1431 1441
1432 if (CurrentToken() == Token::kPERIOD) { 1442 if (CurrentToken() == Token::kPERIOD) {
1433 ConsumeToken(); 1443 ConsumeToken();
1434 ctor_suffix = String::Concat( 1444 ctor_suffix = String::Concat(
1435 ctor_suffix, *ExpectIdentifier("constructor name expected")); 1445 ctor_suffix, *ExpectIdentifier("constructor name expected"));
1436 } 1446 }
1437 ctor_name = String::Concat(ctor_name, ctor_suffix); 1447 ctor_name = String::Concat(ctor_name, ctor_suffix);
1438 if (CurrentToken() != Token::kLPAREN) { 1448 if (CurrentToken() != Token::kLPAREN) {
1439 ErrorMsg("parameter list expected"); 1449 ErrorMsg("parameter list expected");
1440 } 1450 }
1441 // 'this' parameter is the first argument to super class constructor. 1451
1452 ArgumentListNode* arguments = new ArgumentListNode(call_pos);
1453 // 'this' parameter is the first argument to constructor.
1442 AstNode* implicit_argument = new LoadLocalNode(call_pos, *receiver); 1454 AstNode* implicit_argument = new LoadLocalNode(call_pos, *receiver);
1443 ArgumentListNode* arguments = 1455 arguments->Add(implicit_argument);
1444 ParseActualParameters(implicit_argument, kAllowConst); 1456 // Constructor phase parameter is second argument.
1457 LocalVariable* phase_param = LookupPhaseParameter();
1458 ASSERT(phase_param != NULL);
1459 AstNode* phase_argument = new LoadLocalNode(call_pos, *phase_param);
1460 arguments->Add(phase_argument);
1461 ParseActualParameters(arguments, kAllowConst);
1445 1462
1446 // Resolve the constructor. 1463 // Resolve the constructor.
1447 const Function& redirect_ctor = Function::ZoneHandle( 1464 const Function& redirect_ctor = Function::ZoneHandle(
1448 cls.LookupConstructor(ctor_name)); 1465 cls.LookupConstructor(ctor_name));
1449 if (redirect_ctor.IsNull() || 1466 if (redirect_ctor.IsNull() ||
1450 !redirect_ctor.AreValidArguments(arguments->length(), 1467 !redirect_ctor.AreValidArguments(arguments->length(),
1451 arguments->names())) { 1468 arguments->names())) {
1452 ErrorMsg(call_pos, "constructor '%s' not found", 1469 ErrorMsg(call_pos, "constructor '%s' not found",
1453 ctor_name.ToCString()); 1470 ctor_name.ToCString());
1454 } 1471 }
1455 CheckFunctionIsCallable(call_pos, redirect_ctor); 1472 CheckFunctionIsCallable(call_pos, redirect_ctor);
1456 current_block_->statements->Add( 1473 current_block_->statements->Add(
1457 new StaticCallNode(call_pos, redirect_ctor, arguments)); 1474 new StaticCallNode(call_pos, redirect_ctor, arguments));
1458 } 1475 }
1459 1476
1460 1477
1461 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { 1478 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) {
1462 ASSERT(func.IsConstructor()); 1479 ASSERT(func.IsConstructor());
1463 intptr_t ctor_pos = token_index_; 1480 intptr_t ctor_pos = token_index_;
1464 1481
1465 // Implicit 'this' is the only parameter/local variable. 1482 // Implicit 'this' is the only parameter/local variable.
1466 OpenFunctionBlock(func); 1483 OpenFunctionBlock(func);
1467 1484
1468
1469 // Parse expressions of instance fields that have an explicit 1485 // Parse expressions of instance fields that have an explicit
1470 // initializers. 1486 // initializers.
1471 GrowableArray<FieldInitExpression> initializers; 1487 GrowableArray<FieldInitExpression> initializers;
1472 Class& cls = Class::Handle(func.owner()); 1488 Class& cls = Class::Handle(func.owner());
1473 ParseInitializedInstanceFields(cls, &initializers); 1489 ParseInitializedInstanceFields(cls, &initializers);
1474 1490
1475 LocalVariable* receiver = new LocalVariable( 1491 LocalVariable* receiver = new LocalVariable(
1476 ctor_pos, 1492 ctor_pos,
1477 String::ZoneHandle(String::NewSymbol(kThisName)), 1493 String::ZoneHandle(String::NewSymbol(kThisName)),
1478 Type::ZoneHandle(Type::DynamicType())); 1494 Type::ZoneHandle(Type::DynamicType()));
1479 current_block_->scope->AddVariable(receiver); 1495 current_block_->scope->AddVariable(receiver);
1480 1496
1497 LocalVariable* phase_parameter = new LocalVariable(
1498 ctor_pos,
1499 String::ZoneHandle(String::NewSymbol(kPhaseParameterName)),
1500 Type::ZoneHandle(Type::DynamicType()));
1501 current_block_->scope->AddVariable(phase_parameter);
1502
1481 // Now that the "this" parameter is in scope, we can generate the code 1503 // Now that the "this" parameter is in scope, we can generate the code
1482 // to strore the initializer expressions in the respective instance fields. 1504 // to strore the initializer expressions in the respective instance fields.
1483 for (int i = 0; i < initializers.length(); i++) { 1505 for (int i = 0; i < initializers.length(); i++) {
1484 const Field* field = initializers[i].inst_field; 1506 const Field* field = initializers[i].inst_field;
1485 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); 1507 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver);
1486 AstNode* field_init = 1508 AstNode* field_init =
1487 new StoreInstanceFieldNode(field->token_index(), 1509 new StoreInstanceFieldNode(field->token_index(),
1488 instance, 1510 instance,
1489 *field, 1511 *field,
1490 initializers[i].expr); 1512 initializers[i].expr);
1491 current_block_->statements->Add(field_init); 1513 current_block_->statements->Add(field_init);
1492 } 1514 }
1493 1515
1494 GenerateSuperInitializerCall(cls, receiver); 1516 GenerateSuperConstructorCall(cls, receiver);
1495 CheckConstFieldsInitialized(cls); 1517 CheckConstFieldsInitialized(cls);
1496 1518
1497 // Empty constructor body. 1519 // Empty constructor body.
1498 SequenceNode* statements = CloseBlock(); 1520 SequenceNode* statements = CloseBlock();
1499 return statements; 1521 return statements;
1500 } 1522 }
1501 1523
1502 1524
1503 // Parser is at the opening parenthesis of the formal parameter declaration 1525 // Parser is at the opening parenthesis of the formal parameter declaration
1504 // of function. Parse the formal parameters and code. 1526 // of function. Parse the formal parameters and code.
(...skipping 19 matching lines...) Expand all
1524 // The first parameter of a factory is the TypeArguments vector of the type 1546 // The first parameter of a factory is the TypeArguments vector of the type
1525 // of the instance to be allocated. We name this hidden parameter 'this'. 1547 // of the instance to be allocated. We name this hidden parameter 'this'.
1526 const bool has_receiver = !func.IsClosureFunction() && 1548 const bool has_receiver = !func.IsClosureFunction() &&
1527 (!func.is_static() || func.IsConstructor() || func.IsFactory()); 1549 (!func.is_static() || func.IsConstructor() || func.IsFactory());
1528 const bool are_implicitly_final = func.is_const() && func.IsConstructor(); 1550 const bool are_implicitly_final = func.is_const() && func.IsConstructor();
1529 const bool allow_explicit_default_values = true; 1551 const bool allow_explicit_default_values = true;
1530 ASSERT(CurrentToken() == Token::kLPAREN); 1552 ASSERT(CurrentToken() == Token::kLPAREN);
1531 if (has_receiver) { 1553 if (has_receiver) {
1532 params.AddReceiver(token_index_); 1554 params.AddReceiver(token_index_);
1533 } 1555 }
1556 if (func.IsConstructor()) {
1557 // Add implicit parameter for constructor phase.
1558 params.AddFinalParameter(token_index_, kPhaseParameterName,
1559 &Type::ZoneHandle(Type::DynamicType()));
1560 }
1534 if (are_implicitly_final) { 1561 if (are_implicitly_final) {
1535 params.SetImplicitlyFinal(); 1562 params.SetImplicitlyFinal();
1536 } 1563 }
1537 ParseFormalParameterList(allow_explicit_default_values, &params); 1564 ParseFormalParameterList(allow_explicit_default_values, &params);
1538 1565
1539 // The number of parameters and their type are not yet set in local functions, 1566 // The number of parameters and their type are not yet set in local functions,
1540 // since they are not 'top-level' parsed. 1567 // since they are not 'top-level' parsed.
1541 if (func.IsLocalFunction()) { 1568 if (func.IsLocalFunction()) {
1542 AddFormalParamsToFunction(&params, func); 1569 AddFormalParamsToFunction(&params, func);
1543 } 1570 }
1544 SetupDefaultsForOptionalParams(&params, default_parameter_values); 1571 SetupDefaultsForOptionalParams(&params, default_parameter_values);
1545 ASSERT(Type::Handle(func.result_type()).IsResolved()); 1572 ASSERT(Type::Handle(func.result_type()).IsResolved());
1546 ASSERT(func.NumberOfParameters() == params.parameters->length()); 1573 ASSERT(func.NumberOfParameters() == params.parameters->length());
1547 1574
1548 // If this is a constructor, initialize instance fields that have an 1575 // If this is a constructor, initialize instance fields that have an
1549 // explicit initializer expression. This has to be done before code 1576 // explicit initializer expression. This has to be done before code
1550 // for field initializer parameters are is generated. 1577 // for field initializer parameters are is generated.
1551 // NB: the instance field initializers have to be compiled before 1578 // NB: the instance field initializers have to be compiled before
1552 // the parameters are added to the scope, so that a parameter 1579 // the parameters are added to the scope, so that a parameter
1553 // name cannot shadow a name used in the field initializer expression. 1580 // name cannot shadow a name used in the field initializer expression.
1581 SequenceNode* init_statements = NULL;
1582 if (func.IsConstructor()) {
1583 GrowableArray<FieldInitExpression> initializers;
1584 ParseInitializedInstanceFields(cls, &initializers);
1554 1585
1555 GrowableArray<FieldInitExpression> initializers; 1586 // Now populate function scope with the formal parameters.
1556 if (func.IsConstructor()) { 1587 AddFormalParamsToScope(&params, current_block_->scope);
1557 ParseInitializedInstanceFields(cls, &initializers); 1588 LocalVariable* receiver = current_block_->scope->VariableAt(0);
1558 }
1559 1589
1560 // Now populate function scope with the formal parameters. 1590 // Now that the "this" parameter is in scope, we can generate the code
1561 AddFormalParamsToScope(&params, current_block_->scope); 1591 // to strore the initializer expressions in the respective instance fields.
1592 // We do this before the field parameters and the initializers from the
1593 // constructor's initializer list get compiled.
1594 OpenBlock();
1595 if (initializers.length() > 0) {
1596 for (int i = 0; i < initializers.length(); i++) {
1597 const Field* field = initializers[i].inst_field;
1598 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver);
1599 AstNode* field_init =
1600 new StoreInstanceFieldNode(field->token_index(),
1601 instance,
1602 *field,
1603 initializers[i].expr);
1604 current_block_->statements->Add(field_init);
1605 }
1606 }
1562 1607
1563 // Now that the "this" parameter is in scope, we can generate the code 1608 // Turn formal field parameters into field initializers or report error
1564 // to strore the initializer expressions in the respective instance fields. 1609 // if the function is not a constructor
1565 // We do this before the field parameters and the initializers from the 1610 if (params.has_field_initializer) {
1566 // constuctor's initializer list get compiled. 1611 for (int i = 0; i < params.parameters->length(); i++) {
1567 if (initializers.length() > 0) { 1612 ParamDesc& param = (*params.parameters)[i];
1568 LocalVariable* receiver = current_block_->scope->VariableAt(0); 1613 if (param.is_field_initializer) {
1569 for (int i = 0; i < initializers.length(); i++) { 1614 if (!func.IsConstructor()) {
1570 const Field* field = initializers[i].inst_field; 1615 ErrorMsg(param.name_pos,
1571 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); 1616 "field initializer only allowed in constructors");
1572 AstNode* field_init = 1617 }
1573 new StoreInstanceFieldNode(field->token_index(), 1618
1574 instance, 1619 const String& field_name = *param.name;
1575 *field, 1620 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1576 initializers[i].expr); 1621 if (field.IsNull()) {
1577 current_block_->statements->Add(field_init); 1622 ErrorMsg(param.name_pos,
1623 "unresolved reference to instance field '%s'",
1624 field_name.ToCString());
1625 }
1626 const String& mangled_name =
1627 String::ZoneHandle(MangledInitParamName(field_name));
1628 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver);
1629 LocalVariable* p =
1630 current_block_->scope->LookupVariable(mangled_name, false);
1631 ASSERT(p != NULL);
1632 AstNode* value = new LoadLocalNode(param.name_pos, *p);
1633 AstNode* initializer = new StoreInstanceFieldNode(
1634 param.name_pos, instance, field, value);
1635 current_block_->statements->Add(initializer);
1636 }
1637 }
1578 } 1638 }
1579 } 1639 ParseInitializers(cls, receiver);
1580 1640 init_statements = CloseBlock();
1581 // Turn formal field parameters into field initializers or report error 1641 LocalVariable* phase_param = LookupPhaseParameter();
1582 // if the function is not a constructor 1642 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param);
1583 if (params.has_field_initializer) { 1643 AstNode* phase_check =
1584 LocalVariable* receiver = current_block_->scope->VariableAt(0); 1644 new BinaryOpNode(token_index_, Token::kBIT_AND,
1585 for (int i = 0; i < params.parameters->length(); i++) { 1645 phase_value,
1586 ParamDesc& param = (*params.parameters)[i]; 1646 new LiteralNode(token_index_,
1587 if (param.is_field_initializer) { 1647 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1588 if (!func.IsConstructor()) { 1648 AstNode* comparison =
1649 new ComparisonNode(token_index_, Token::kNE_STRICT,
1650 phase_check,
1651 new LiteralNode(token_index_, Smi::ZoneHandle(Smi::New(0))));
1652 AstNode* guarded_init_statements =
1653 new IfNode(token_index_, comparison, init_statements, NULL);
1654 current_block_->statements->Add(guarded_init_statements);
1655 } else {
1656 // Parsing a function that is not a constructor.
1657 if (params.has_field_initializer) {
1658 for (int i = 0; i < params.parameters->length(); i++) {
1659 ParamDesc& param = (*params.parameters)[i];
1660 if (param.is_field_initializer) {
1589 ErrorMsg(param.name_pos, 1661 ErrorMsg(param.name_pos,
1590 "field initializer only allowed in constructors"); 1662 "field initializer only allowed in constructors");
1591 } 1663 }
1592
1593 const String& field_name = *param.name;
1594 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1595 if (field.IsNull()) {
1596 ErrorMsg(param.name_pos,
1597 "unresolved reference to instance field '%s'",
1598 field_name.ToCString());
1599 }
1600 const String& mangled_name =
1601 String::ZoneHandle(MangledInitParamName(field_name));
1602 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver);
1603 LocalVariable* p =
1604 current_block_->scope->LocalLookupVariable(mangled_name);
1605 ASSERT(p != NULL);
1606 AstNode* value = new LoadLocalNode(param.name_pos, *p);
1607 AstNode* initializer =
1608 new StoreInstanceFieldNode(param.name_pos, instance, field, value);
1609 current_block_->statements->Add(initializer);
1610 } 1664 }
1611 } 1665 }
1612 } 1666 // Populate function scope with the formal parameters.
1613 1667 AddFormalParamsToScope(&params, current_block_->scope);
1614 if (func.IsConstructor()) {
1615 ParseInitializers(cls);
1616 } 1668 }
1617 1669
1618 if (FLAG_enable_type_checks && 1670 if (FLAG_enable_type_checks &&
1619 (current_block_->scope->function_level() > 0)) { 1671 (current_block_->scope->function_level() > 0)) {
1620 // We are parsing, but not compiling, a local function. 1672 // We are parsing, but not compiling, a local function.
1621 // The instantiator may be required at run time for generic type checks. 1673 // The instantiator may be required at run time for generic type checks.
1622 if ((current_class().NumTypeParameters() > 0) && 1674 if ((current_class().NumTypeParameters() > 0) &&
1623 (!current_function().is_static() || 1675 (!current_function().is_static() ||
1624 current_function().IsInFactoryScope())) { 1676 current_function().IsInFactoryScope())) {
1625 // Make sure that the receiver of the enclosing instance function 1677 // Make sure that the receiver of the enclosing instance function
1626 // (or implicit first parameter of an enclosing factory) is marked as 1678 // (or implicit first parameter of an enclosing factory) is marked as
1627 // captured if type checks are enabled, because they may access the 1679 // captured if type checks are enabled, because they may access the
1628 // receiver to instantiate types. 1680 // receiver to instantiate types.
1629 CaptureReceiver(); 1681 CaptureReceiver();
1630 } 1682 }
1631 } 1683 }
1632 1684
1685 if (func.IsConstructor()) {
1686 LocalVariable* receiver = current_block_->scope->VariableAt(0);
1687 StaticCallNode* super_call = NULL;
1688 ASSERT(init_statements != NULL);
1689 // Look for the super initializer call in the sequence of initializer
1690 // statements. If it exists and is not the last initializer statement,
1691 // we need to create an implicit super call to the super constructor's
1692 // body.
1693 // Thus, iterate over all but the last initializer to see whether
1694 // it's a super constructor call.
1695 for (int i = 0; i < init_statements->length() - 1; i++) {
1696 if (init_statements->NodeAt(i)->IsStaticCallNode()) {
1697 StaticCallNode* static_call =
1698 init_statements->NodeAt(i)->AsStaticCallNode();
1699 if (static_call->function().IsConstructor()) {
1700 super_call = static_call;
1701 break;
1702 }
1703 }
1704 }
1705 if (super_call != NULL) {
1706 // Generate an implicit call to the super constructor's body.
1707 // We need to patch the super _initializer_ call so that it
1708 // saves the evaluated actual arguments in temporary variables.
1709 // The temporary variables are necessary so that the argument
1710 // expressions are not evaluated twice.
1711 ArgumentListNode* ctor_args = super_call->arguments();
1712 // The super initializer call has at least 2 arguments: the
1713 // implicit receiver, and the hidden constructor phase.
1714 ASSERT(ctor_args->length() >= 2);
1715 for (int i = 2; i < ctor_args->length(); i++) {
1716 AstNode* arg = ctor_args->NodeAt(i);
1717 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) {
1718 LocalVariable* temp =
1719 CreateTempConstVariable(arg->token_index(), arg->id(), "sca");
1720 AstNode* save_temp =
1721 new StoreLocalNode(arg->token_index(), *temp, arg);
1722 ctor_args->SetNodeAt(i, save_temp);
1723 }
1724 }
1725 }
1726 OpenBlock();
1727 if (super_call != NULL) {
1728 ArgumentListNode* initializer_args = super_call->arguments();
1729 const Function& super_ctor = super_call->function();
1730 // Patch the initializer call so it only executes the super
1731 // initializer.
1732 initializer_args->SetNodeAt(1,
1733 new LiteralNode(token_index_,
1734 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1735
1736 ArgumentListNode* super_call_args = new ArgumentListNode(token_index_);
1737 // First argument is the receiver.
1738 super_call_args->Add(new LoadLocalNode(token_index_, *receiver));
1739 // Second argument is the constructor phase argument.
1740 AstNode* phase_parameter =
1741 new LiteralNode(token_index_,
1742 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)));
1743 super_call_args->Add(phase_parameter);
1744 for (int i = 2; i < initializer_args->length(); i++) {
1745 AstNode* arg = initializer_args->NodeAt(i);
1746 if (arg->IsLiteralNode()) {
1747 LiteralNode* lit = arg->AsLiteralNode();
1748 super_call_args->Add(new LiteralNode(token_index_, lit->literal()));
1749 } else {
1750 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode());
1751 if (arg->IsLoadLocalNode()) {
1752 const LocalVariable& temp = arg->AsLoadLocalNode()->local();
1753 super_call_args->Add(new LoadLocalNode(token_index_, temp));
1754 } else if (arg->IsStoreLocalNode()) {
1755 const LocalVariable& temp = arg->AsStoreLocalNode()->local();
1756 super_call_args->Add(new LoadLocalNode(token_index_, temp));
1757 }
1758 }
1759 }
1760 ASSERT(super_ctor.AreValidArguments(super_call_args->length(),
1761 super_call_args->names()));
1762 current_block_->statements->Add(
1763 new StaticCallNode(token_index_, super_ctor, super_call_args));
1764 }
1765 }
1633 if (CurrentToken() == Token::kLBRACE) { 1766 if (CurrentToken() == Token::kLBRACE) {
1634 ConsumeToken(); 1767 ConsumeToken();
1635 ParseStatementSequence(); 1768 ParseStatementSequence();
1636 ExpectToken(Token::kRBRACE); 1769 ExpectToken(Token::kRBRACE);
1637 } else if (CurrentToken() == Token::kARROW) { 1770 } else if (CurrentToken() == Token::kARROW) {
1638 ConsumeToken(); 1771 ConsumeToken();
1639 intptr_t expr_pos = token_index_; 1772 intptr_t expr_pos = token_index_;
1640 AstNode* expr = ParseExpr(kAllowConst); 1773 AstNode* expr = ParseExpr(kAllowConst);
1641 ASSERT(expr != NULL); 1774 ASSERT(expr != NULL);
1642 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 1775 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
1643 } else if (IsLiteral("native")) { 1776 } else if (IsLiteral("native")) {
1644 ParseNativeFunctionBlock(&params, func); 1777 ParseNativeFunctionBlock(&params, func);
1645 } else if (CurrentToken() == Token::kSEMICOLON) { 1778 } else if (CurrentToken() == Token::kSEMICOLON) {
1646 ConsumeToken(); 1779 ConsumeToken();
1647 ASSERT(func.IsConstructor()); 1780 ASSERT(func.IsConstructor());
1648 // Some constructors have no function body. 1781 // Some constructors have no function body.
1649 } else { 1782 } else {
1650 UnexpectedToken(); 1783 UnexpectedToken();
1651 } 1784 }
1785 if (func.IsConstructor()) {
1786 SequenceNode* ctor_block = CloseBlock();
1787 LocalVariable* phase_param = LookupPhaseParameter();
1788 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param);
1789 AstNode* phase_check =
1790 new BinaryOpNode(token_index_, Token::kBIT_AND,
1791 phase_value,
1792 new LiteralNode(token_index_,
1793 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))));
1794 AstNode* comparison =
1795 new ComparisonNode(token_index_, Token::kNE_STRICT,
1796 phase_check,
1797 new LiteralNode(token_index_, Smi::ZoneHandle(Smi::New(0))));
1798 AstNode* guarded_block_statements =
1799 new IfNode(token_index_, comparison, ctor_block, NULL);
1800 current_block_->statements->Add(guarded_block_statements);
1801 }
1652 1802
1653 SequenceNode* statements = CloseBlock(); 1803 SequenceNode* statements = CloseBlock();
1654 return statements; 1804 return statements;
1655 } 1805 }
1656 1806
1657 1807
1658 void Parser::SkipIf(Token::Kind token) { 1808 void Parser::SkipIf(Token::Kind token) {
1659 if (CurrentToken() == token) { 1809 if (CurrentToken() == token) {
1660 ConsumeToken(); 1810 ConsumeToken();
1661 } 1811 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1789 const bool has_this_param = 1939 const bool has_this_param =
1790 !method->has_static || method->IsConstructor() || method->has_factory; 1940 !method->has_static || method->IsConstructor() || method->has_factory;
1791 const bool are_implicitly_final = method->has_const; 1941 const bool are_implicitly_final = method->has_const;
1792 const bool allow_explicit_default_values = 1942 const bool allow_explicit_default_values =
1793 (!method->has_abstract && !members->is_interface()); 1943 (!method->has_abstract && !members->is_interface());
1794 const intptr_t formal_param_pos = token_index_; 1944 const intptr_t formal_param_pos = token_index_;
1795 method->params.Clear(); 1945 method->params.Clear();
1796 if (has_this_param) { 1946 if (has_this_param) {
1797 method->params.AddReceiver(formal_param_pos); 1947 method->params.AddReceiver(formal_param_pos);
1798 } 1948 }
1949 // Constructors have an implicit parameter for the constructor phase.
1950 if (method->IsConstructor()) {
1951 method->params.AddFinalParameter(token_index_, kPhaseParameterName,
1952 &Type::ZoneHandle(Type::DynamicType()));
1953 }
1799 if (are_implicitly_final) { 1954 if (are_implicitly_final) {
1800 method->params.SetImplicitlyFinal(); 1955 method->params.SetImplicitlyFinal();
1801 } 1956 }
1802 ParseFormalParameterList(allow_explicit_default_values, &method->params); 1957 ParseFormalParameterList(allow_explicit_default_values, &method->params);
1803 if (method->IsGetter() || method->IsSetter()) { 1958 if (method->IsGetter() || method->IsSetter()) {
1804 int expected_num_parameters = 0; 1959 int expected_num_parameters = 0;
1805 if (method->IsGetter()) { 1960 if (method->IsGetter()) {
1806 expected_num_parameters = (method->has_static) ? 0 : 1; 1961 expected_num_parameters = (method->has_static) ? 0 : 1;
1807 method->name = &String::ZoneHandle(Field::GetterName(*method->name)); 1962 method->name = &String::ZoneHandle(Field::GetterName(*method->name));
1808 } else { 1963 } else {
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2300 cls.SetFunctions(Array::Handle(NewArray<Function>(members.functions()))); 2455 cls.SetFunctions(Array::Handle(NewArray<Function>(members.functions())));
2301 classes->Add(&cls); 2456 classes->Add(&cls);
2302 } 2457 }
2303 2458
2304 2459
2305 // 1. Add an implicit constructor if no explicit constructor is present. 2460 // 1. Add an implicit constructor if no explicit constructor is present.
2306 // 2. Check for cycles in constructor redirection. 2461 // 2. Check for cycles in constructor redirection.
2307 void Parser::CheckConstructors(ClassDesc* class_desc) { 2462 void Parser::CheckConstructors(ClassDesc* class_desc) {
2308 // Add an implicit constructor if no explicit constructor is present. 2463 // Add an implicit constructor if no explicit constructor is present.
2309 if (!class_desc->has_constructor()) { 2464 if (!class_desc->has_constructor()) {
2310 // The implicit constructor is unnamed, has no parameter, and contains 2465 // The implicit constructor is unnamed, has no explicit parameter,
2311 // a supercall in the initializer list. 2466 // and contains a supercall in the initializer list.
2312 String& ctor_name = String::ZoneHandle( 2467 String& ctor_name = String::ZoneHandle(
2313 String::Concat(class_desc->class_name(), 2468 String::Concat(class_desc->class_name(),
2314 String::Handle(String::NewSymbol(".")))); 2469 String::Handle(String::NewSymbol("."))));
2315 ctor_name = String::NewSymbol(ctor_name); 2470 ctor_name = String::NewSymbol(ctor_name);
2316 Function& ctor = Function::ZoneHandle( 2471 Function& ctor = Function::ZoneHandle(
2317 Function::New(ctor_name, 2472 Function::New(ctor_name,
2318 RawFunction::kConstructor, 2473 RawFunction::kConstructor,
2319 /* is_static = */ false, 2474 /* is_static = */ false,
2320 /* is_const = */ false, 2475 /* is_const = */ false,
2321 class_desc->token_pos())); 2476 class_desc->token_pos()));
2322 ParamList params; 2477 ParamList params;
2478 // Add implicit 'this' parameter.
2323 params.AddReceiver(token_index_); 2479 params.AddReceiver(token_index_);
2480 // Add implicit parameter for constructor phase.
2481 params.AddFinalParameter(token_index_, kPhaseParameterName,
2482 &Type::ZoneHandle(Type::DynamicType()));
2483
2324 AddFormalParamsToFunction(&params, ctor); 2484 AddFormalParamsToFunction(&params, ctor);
2325 // TODO(regis): What are the type arguments? 2485 // TODO(regis): What are the type arguments?
2326 Type& result_type = Type::ZoneHandle( 2486 Type& result_type = Type::ZoneHandle(
2327 Type::NewRawType(Class::Handle(class_desc->clazz()))); 2487 Type::NewRawType(Class::Handle(class_desc->clazz())));
2328 ctor.set_result_type(result_type); 2488 ctor.set_result_type(result_type);
2329 class_desc->AddFunction(&ctor); 2489 class_desc->AddFunction(&ctor);
2330 } 2490 }
2331 2491
2332 // Check for cycles in constructor redirection. 2492 // Check for cycles in constructor redirection.
2333 const GrowableArray<MemberDesc>& members = class_desc->members(); 2493 const GrowableArray<MemberDesc>& members = class_desc->members();
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
3193 } 3353 }
3194 3354
3195 3355
3196 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, 3356 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope,
3197 bool test_only) { 3357 bool test_only) {
3198 const String& this_name = String::Handle(String::NewSymbol(kThisName)); 3358 const String& this_name = String::Handle(String::NewSymbol(kThisName));
3199 return from_scope->LookupVariable(this_name, test_only); 3359 return from_scope->LookupVariable(this_name, test_only);
3200 } 3360 }
3201 3361
3202 3362
3363 LocalVariable* Parser::LookupPhaseParameter() {
3364 const String& phase_name =
3365 String::Handle(String::NewSymbol(kPhaseParameterName));
3366 const bool kTestOnly = false;
3367 return current_block_->scope->LookupVariable(phase_name, kTestOnly);
3368 }
3369
3370
3203 void Parser::CaptureReceiver() { 3371 void Parser::CaptureReceiver() {
3204 ASSERT(current_block_->scope->function_level() > 0); 3372 ASSERT(current_block_->scope->function_level() > 0);
3205 const bool kTestOnly = false; 3373 const bool kTestOnly = false;
3206 // Side effect of lookup captures the receiver variable. 3374 // Side effect of lookup captures the receiver variable.
3207 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); 3375 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly);
3208 ASSERT(receiver != NULL); 3376 ASSERT(receiver != NULL);
3209 } 3377 }
3210 3378
3211 3379
3212 AstNode* Parser::LoadReceiver(intptr_t token_pos) { 3380 AstNode* Parser::LoadReceiver(intptr_t token_pos) {
(...skipping 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after
5193 Unimplemented("incr operation not implemented"); 5361 Unimplemented("incr operation not implemented");
5194 } 5362 }
5195 expr = incr_op_node; 5363 expr = incr_op_node;
5196 } else { 5364 } else {
5197 expr = ParsePostfixExpr(); 5365 expr = ParsePostfixExpr();
5198 } 5366 }
5199 return expr; 5367 return expr;
5200 } 5368 }
5201 5369
5202 5370
5203 ArgumentListNode* Parser::ParseActualParameters(AstNode* implicit_argument, 5371 ArgumentListNode* Parser::ParseActualParameters(
5204 bool require_const) { 5372 ArgumentListNode* implicit_arguments,
5373 bool require_const) {
5205 TRACE_PARSER("ParseActualParameters"); 5374 TRACE_PARSER("ParseActualParameters");
5206 ASSERT(CurrentToken() == Token::kLPAREN); 5375 ASSERT(CurrentToken() == Token::kLPAREN);
5207 const bool saved_mode = SetAllowFunctionLiterals(true); 5376 const bool saved_mode = SetAllowFunctionLiterals(true);
5208 ArgumentListNode* arguments = new ArgumentListNode(token_index_); 5377 ArgumentListNode* arguments;
5209 if (implicit_argument != NULL) { 5378 if (implicit_arguments == NULL) {
5210 arguments->Add(implicit_argument); 5379 arguments = new ArgumentListNode(token_index_);
5380 } else {
5381 arguments = implicit_arguments;
5211 } 5382 }
5212 GrowableArray<const String*> names; 5383 GrowableArray<const String*> names;
5213 bool named_argument_seen = false; 5384 bool named_argument_seen = false;
5214 if (LookaheadToken(1) != Token::kRPAREN) { 5385 if (LookaheadToken(1) != Token::kRPAREN) {
5215 do { 5386 do {
5216 ASSERT((CurrentToken() == Token::kLPAREN) || 5387 ASSERT((CurrentToken() == Token::kLPAREN) ||
5217 (CurrentToken() == Token::kCOMMA)); 5388 (CurrentToken() == Token::kCOMMA));
5218 ConsumeToken(); 5389 ConsumeToken();
5219 if ((CurrentToken() == Token::kIDENT) && 5390 if ((CurrentToken() == Token::kIDENT) &&
5220 (LookaheadToken(1) == Token::kCOLON)) { 5391 (LookaheadToken(1) == Token::kCOLON)) {
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
5800 field.set_value(const_value); 5971 field.set_value(const_value);
5801 } 5972 }
5802 } 5973 }
5803 5974
5804 5975
5805 RawInstance* Parser::EvaluateConstConstructorCall( 5976 RawInstance* Parser::EvaluateConstConstructorCall(
5806 const Class& type_class, 5977 const Class& type_class,
5807 const TypeArguments& type_arguments, 5978 const TypeArguments& type_arguments,
5808 const Function& constructor, 5979 const Function& constructor,
5809 ArgumentListNode* arguments) { 5980 ArgumentListNode* arguments) {
5810 GrowableArray<const Object*> arg_values(arguments->length() + 1); 5981 // +2 for implicit receiver and constructor phase arguments.
5982 GrowableArray<const Object*> arg_values(arguments->length() + 2);
5811 Instance& instance = Instance::Handle(); 5983 Instance& instance = Instance::Handle();
5812 if (!constructor.IsFactory()) { 5984 if (!constructor.IsFactory()) {
5813 instance = Instance::New(type_class); 5985 instance = Instance::New(type_class);
5814 if (!type_arguments.IsNull()) { 5986 if (!type_arguments.IsNull()) {
5815 // TODO(regis): Where should we check the constraints on type parameters? 5987 // TODO(regis): Where should we check the constraints on type parameters?
5816 if (!type_arguments.IsInstantiated()) { 5988 if (!type_arguments.IsInstantiated()) {
5817 ErrorMsg("type must be constant in const constructor"); 5989 ErrorMsg("type must be constant in const constructor");
5818 } 5990 }
5819 instance.SetTypeArguments(type_arguments); 5991 instance.SetTypeArguments(type_arguments);
5820 } 5992 }
5821 arg_values.Add(&instance); 5993 arg_values.Add(&instance);
5994 arg_values.Add(&Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
5822 } else { 5995 } else {
5823 // Prepend type_arguments to list of arguments to factory. 5996 // Prepend type_arguments to list of arguments to factory.
5824 ASSERT(type_arguments.IsZoneHandle()); 5997 ASSERT(type_arguments.IsZoneHandle());
5825 arg_values.Add(&type_arguments); 5998 arg_values.Add(&type_arguments);
5826 } 5999 }
5827 for (int i = 0; i < arguments->length(); i++) { 6000 for (int i = 0; i < arguments->length(); i++) {
5828 AstNode* arg = arguments->NodeAt(i); 6001 AstNode* arg = arguments->NodeAt(i);
5829 // Arguments have been evaluated to a literal value already. 6002 // Arguments have been evaluated to a literal value already.
5830 ASSERT(arg->IsLiteralNode()); 6003 ASSERT(arg->IsLiteralNode());
5831 arg_values.Add(&arg->AsLiteralNode()->literal()); 6004 arg_values.Add(&arg->AsLiteralNode()->literal());
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
6476 } 6649 }
6477 6650
6478 // Parse constructor parameters. 6651 // Parse constructor parameters.
6479 if (CurrentToken() != Token::kLPAREN) { 6652 if (CurrentToken() != Token::kLPAREN) {
6480 ErrorMsg("'(' expected"); 6653 ErrorMsg("'(' expected");
6481 } 6654 }
6482 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); 6655 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const);
6483 6656
6484 // A constructor has an implicit 'this' parameter (instance to construct) 6657 // A constructor has an implicit 'this' parameter (instance to construct)
6485 // and a factory has an implicit 'this' parameter (type_arguments). 6658 // and a factory has an implicit 'this' parameter (type_arguments).
6486 intptr_t arguments_length = arguments->length() + 1; 6659 // A constructor has a second implicit 'phase' parameter.
6660 intptr_t arguments_length = arguments->length() + 2;
6487 6661
6488 if (type_class.is_interface()) { 6662 if (type_class.is_interface()) {
6489 // We need to make sure that an appropriate constructor is 6663 // We need to make sure that an appropriate constructor is
6490 // declared in the interface. 6664 // declared in the interface.
6491 const String& constructor_name = 6665 const String& constructor_name =
6492 BuildConstructorName(type_class_name, named_constructor); 6666 BuildConstructorName(type_class_name, named_constructor);
6493 const String& external_constructor_name = 6667 const String& external_constructor_name =
6494 (named_constructor ? constructor_name : type_class_name); 6668 (named_constructor ? constructor_name : type_class_name);
6495 Function& constructor = Function::ZoneHandle( 6669 Function& constructor = Function::ZoneHandle(
6496 type_class.LookupConstructor(constructor_name)); 6670 type_class.LookupConstructor(constructor_name));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6541 6715
6542 // Make sure that an appropriate constructor exists. 6716 // Make sure that an appropriate constructor exists.
6543 const String& constructor_name = 6717 const String& constructor_name =
6544 BuildConstructorName(type_class_name, named_constructor); 6718 BuildConstructorName(type_class_name, named_constructor);
6545 const String& external_constructor_name = 6719 const String& external_constructor_name =
6546 (named_constructor ? constructor_name : type_class_name); 6720 (named_constructor ? constructor_name : type_class_name);
6547 Function& constructor = Function::ZoneHandle( 6721 Function& constructor = Function::ZoneHandle(
6548 type_class.LookupConstructor(constructor_name)); 6722 type_class.LookupConstructor(constructor_name));
6549 if (constructor.IsNull()) { 6723 if (constructor.IsNull()) {
6550 constructor = type_class.LookupFactory(constructor_name); 6724 constructor = type_class.LookupFactory(constructor_name);
6725 // A factory does not have the implicit 'phase' parameter.
6726 arguments_length -= 1;
6551 } 6727 }
6552 if (constructor.IsNull()) { 6728 if (constructor.IsNull()) {
6553 ErrorMsg(new_pos, "class '%s' has no constructor or factory named '%s'", 6729 ErrorMsg(new_pos, "class '%s' has no constructor or factory named '%s'",
6554 String::Handle(type_class.Name()).ToCString(), 6730 String::Handle(type_class.Name()).ToCString(),
6555 external_constructor_name.ToCString()); 6731 external_constructor_name.ToCString());
6556 } 6732 }
6557 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { 6733 if (!constructor.AreValidArguments(arguments_length, arguments->names())) {
6558 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " 6734 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' "
6559 "for class '%s'", 6735 "for class '%s'",
6560 external_constructor_name.ToCString(), 6736 external_constructor_name.ToCString(),
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
7022 } 7198 }
7023 7199
7024 7200
7025 void Parser::SkipNestedExpr() { 7201 void Parser::SkipNestedExpr() {
7026 const bool saved_mode = SetAllowFunctionLiterals(true); 7202 const bool saved_mode = SetAllowFunctionLiterals(true);
7027 SkipExpr(); 7203 SkipExpr();
7028 SetAllowFunctionLiterals(saved_mode); 7204 SetAllowFunctionLiterals(saved_mode);
7029 } 7205 }
7030 7206
7031 } // namespace dart 7207 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698