OLD | NEW |
---|---|
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 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1192 | 1192 |
1193 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos); | 1193 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos); |
1194 setter_arguments->Add(implicit_argument); | 1194 setter_arguments->Add(implicit_argument); |
1195 setter_arguments->Add(value); | 1195 setter_arguments->Add(value); |
1196 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); | 1196 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); |
1197 } | 1197 } |
1198 return super_field; | 1198 return super_field; |
1199 } | 1199 } |
1200 | 1200 |
1201 | 1201 |
1202 void Parser::GenerateSuperInitializerCall(const Class& cls, | |
1203 LocalVariable* receiver) { | |
1204 const intptr_t supercall_pos = token_index_; | |
1205 const Class& super_class = Class::Handle(cls.SuperClass()); | |
1206 // Omit the implicit super() if there is no super class (i.e. | |
1207 // we're not compiling class Object), or if the super class is an | |
1208 // artificially generated "wrapper class" that has no constructor. | |
1209 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { | |
1210 return; | |
1211 } | |
1212 String& ctor_name = String::Handle(super_class.Name()); | |
1213 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | |
1214 ctor_name = String::Concat(ctor_name, ctor_suffix); | |
1215 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | |
1216 // implicit 'this' parameter is the only argument. | |
1217 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); | |
1218 arguments->Add(implicit_argument); | |
1219 const Function& super_ctor = Function::ZoneHandle( | |
1220 super_class.LookupConstructor(ctor_name)); | |
1221 if (super_ctor.IsNull() || | |
1222 !super_ctor.AreValidArguments(arguments->length(), | |
1223 arguments->names())) { | |
1224 ErrorMsg(supercall_pos, | |
1225 "unresolved implicit call to super constructor '%s()'", | |
1226 String::Handle(super_class.Name()).ToCString()); | |
1227 } | |
1228 CheckFunctionIsCallable(supercall_pos, super_ctor); | |
1229 current_block_->statements->Add( | |
1230 new StaticCallNode(supercall_pos, super_ctor, arguments)); | |
1231 } | |
1232 | |
1233 | |
1202 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 1234 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
1203 LocalVariable* receiver) { | 1235 LocalVariable* receiver) { |
1204 TRACE_PARSER("ParseSuperInitializer"); | 1236 TRACE_PARSER("ParseSuperInitializer"); |
1205 ASSERT(CurrentToken() == Token::kSUPER); | 1237 ASSERT(CurrentToken() == Token::kSUPER); |
1206 const intptr_t supercall_pos = token_index_; | 1238 const intptr_t supercall_pos = token_index_; |
1207 ConsumeToken(); | 1239 ConsumeToken(); |
1208 const Class& super_class = Class::Handle(cls.SuperClass()); | 1240 const Class& super_class = Class::Handle(cls.SuperClass()); |
1209 ASSERT(!super_class.IsNull()); | 1241 ASSERT(!super_class.IsNull()); |
1210 String& ctor_name = String::Handle(super_class.Name()); | 1242 String& ctor_name = String::Handle(super_class.Name()); |
1211 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1243 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1321 FieldInitExpression initializer; | 1353 FieldInitExpression initializer; |
1322 initializer.inst_field = &field; | 1354 initializer.inst_field = &field; |
1323 initializer.expr = init_expr; | 1355 initializer.expr = init_expr; |
1324 initializers->Add(initializer); | 1356 initializers->Add(initializer); |
1325 } | 1357 } |
1326 } | 1358 } |
1327 SetPosition(saved_pos); | 1359 SetPosition(saved_pos); |
1328 } | 1360 } |
1329 | 1361 |
1330 | 1362 |
1331 void Parser::ParseInitializers(const Class& cls, LocalVariable* receiver) { | 1363 void Parser::ParseInitializers(const Class& cls) { |
1332 TRACE_PARSER("ParseInitializers"); | 1364 TRACE_PARSER("ParseInitializers"); |
1333 AstNode* init_statement = NULL; | 1365 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1334 AstNode* super_init_statement = NULL; | 1366 bool super_init_seen = false; |
1335 // TODO(4995181): Allow super initializer to appear in any position | 1367 if (CurrentToken() == Token::kCOLON) { |
1336 // of the initializer list. | 1368 ConsumeToken(); |
1337 if (CurrentToken() == Token::kSUPER) { | 1369 if ((CurrentToken() == Token::kTHIS) && |
1338 super_init_statement = ParseSuperInitializer(cls, receiver); | 1370 ((LookaheadToken(1) == Token::kLPAREN) || |
1339 } else { | 1371 ((LookaheadToken(1) == Token::kPERIOD) && |
1340 init_statement = ParseInitializer(cls, receiver); | 1372 (LookaheadToken(3) == Token::kLPAREN)))) { |
1341 current_block_->statements->Add(init_statement); | 1373 // Either we see this(...) or this.xxx(...) which is a |
1374 // redirected constructor. We don't need to check whether | |
1375 // const fields are initialized. The other constructor will | |
1376 // guarantee that. | |
1377 ParseConstructorRedirection(cls, receiver); | |
1378 return; | |
1379 } | |
1380 | |
1381 for (;;) { | |
regis
2011/10/13 19:32:29
If you do not consume the colon above (and increme
hausner
2011/10/13 20:24:09
Nice idea. Done.
| |
1382 AstNode* init_statement = NULL; | |
1383 if (CurrentToken() == Token::kSUPER) { | |
1384 if (super_init_seen) { | |
1385 ErrorMsg("Duplicate call to super constructor"); | |
1386 } | |
1387 init_statement = ParseSuperInitializer(cls, receiver); | |
1388 super_init_seen = true; | |
1389 } else { | |
1390 init_statement = ParseInitializer(cls, receiver); | |
1391 } | |
1392 current_block_->statements->Add(init_statement); | |
1393 if (CurrentToken() != Token::kCOMMA) { | |
1394 break; | |
1395 } | |
1396 ConsumeToken(); | |
1397 } | |
1342 } | 1398 } |
1343 while (CurrentToken() == Token::kCOMMA) { | 1399 |
1344 ConsumeToken(); | 1400 // Generate implicit super() if we haven't seen an explicit super call |
1345 init_statement = ParseInitializer(cls, receiver); | 1401 // or constructor redirection. |
1346 current_block_->statements->Add(init_statement); | 1402 // Omit the implicit super() if there is no super class (i.e. |
1403 // we're not compiling class Object), or if the super class is an | |
1404 // artificially generated "wrapper class" that has no constructor. | |
1405 if (!super_init_seen) { | |
1406 GenerateSuperInitializerCall(cls, receiver); | |
1347 } | 1407 } |
1348 // The call to super constructor is to be done after all initializers. | 1408 |
1349 if (super_init_statement != NULL) { | 1409 CheckConstFieldsInitialized(cls); |
1350 current_block_->statements->Add(super_init_statement); | |
1351 } | |
1352 } | 1410 } |
1353 | 1411 |
1354 | 1412 |
1355 void Parser::ParseConstructorRedirection(const Class& cls, | 1413 void Parser::ParseConstructorRedirection(const Class& cls, |
1356 LocalVariable* receiver) { | 1414 LocalVariable* receiver) { |
1357 ASSERT(CurrentToken() == Token::kTHIS); | 1415 ASSERT(CurrentToken() == Token::kTHIS); |
1358 intptr_t call_pos = token_index_; | 1416 intptr_t call_pos = token_index_; |
1359 ConsumeToken(); | 1417 ConsumeToken(); |
1360 String& ctor_name = String::Handle(cls.Name()); | 1418 String& ctor_name = String::Handle(cls.Name()); |
1361 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1419 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1415 const Field* field = initializers[i].inst_field; | 1473 const Field* field = initializers[i].inst_field; |
1416 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); | 1474 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); |
1417 AstNode* field_init = | 1475 AstNode* field_init = |
1418 new StoreInstanceFieldNode(field->token_index(), | 1476 new StoreInstanceFieldNode(field->token_index(), |
1419 instance, | 1477 instance, |
1420 *field, | 1478 *field, |
1421 initializers[i].expr); | 1479 initializers[i].expr); |
1422 current_block_->statements->Add(field_init); | 1480 current_block_->statements->Add(field_init); |
1423 } | 1481 } |
1424 | 1482 |
1425 // Super call to constructor of super class. | 1483 GenerateSuperInitializerCall(cls, receiver); |
1426 const Class& super_class = Class::Handle(cls.SuperClass()); | |
1427 ASSERT(!super_class.IsNull()); | |
1428 String& ctor_name = String::Handle(super_class.Name()); | |
1429 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | |
1430 ctor_name = String::Concat(ctor_name, ctor_suffix); | |
1431 ctor_name = String::NewSymbol(ctor_name); | |
1432 ArgumentListNode* arguments = new ArgumentListNode(ctor_pos); | |
1433 AstNode* implicit_argument = new LoadLocalNode(ctor_pos, *receiver); | |
1434 arguments->Add(implicit_argument); | |
1435 const Function& super_ctor = Function::ZoneHandle( | |
1436 super_class.LookupConstructor(ctor_name)); | |
1437 if (super_ctor.IsNull() || | |
1438 !super_ctor.AreValidArgumentCounts(arguments->length(), 0)) { | |
1439 ErrorMsg(ctor_pos, | |
1440 "super class constructor '%s' not found", | |
1441 ctor_name.ToCString()); | |
1442 } | |
1443 current_block_->statements->Add( | |
1444 new StaticCallNode(ctor_pos, super_ctor, arguments)); | |
1445 | |
1446 CheckConstFieldsInitialized(cls); | 1484 CheckConstFieldsInitialized(cls); |
1447 | 1485 |
1448 // Empty constructor body. | 1486 // Empty constructor body. |
1449 SequenceNode* statements = CloseBlock(); | 1487 SequenceNode* statements = CloseBlock(); |
1450 return statements; | 1488 return statements; |
1451 } | 1489 } |
1452 | 1490 |
1453 | 1491 |
1454 // Parser is at the opening parenthesis of the formal parameter declaration | 1492 // Parser is at the opening parenthesis of the formal parameter declaration |
1455 // of function. Parse the formal parameters and code. | 1493 // of function. Parse the formal parameters and code. |
1456 SequenceNode* Parser::ParseFunc(const Function& func, | 1494 SequenceNode* Parser::ParseFunc(const Function& func, |
1457 Array& default_parameter_values) { | 1495 Array& default_parameter_values) { |
1458 if (IsLiteral("class")) { | 1496 if (IsLiteral("class")) { |
1459 // Special case: implicit constructor. There is no source text to | 1497 // Special case: implicit constructor. There is no source text to |
1460 // parse. We just build the sequence node by hand. | 1498 // parse. We just build the sequence node by hand. |
1461 return MakeImplicitConstructor(func); | 1499 return MakeImplicitConstructor(func); |
1462 } | 1500 } |
1463 | 1501 |
1502 const Class& cls = Class::Handle(func.owner()); | |
1503 ASSERT(!cls.IsNull()); | |
1504 | |
1464 // Build local scope for function. | 1505 // Build local scope for function. |
1465 OpenFunctionBlock(func); | 1506 OpenFunctionBlock(func); |
1466 | 1507 |
1467 ParamList params; | 1508 ParamList params; |
1468 // Static functions do not have a receiver, except constructors, which are | 1509 // Static functions do not have a receiver, except constructors, which are |
1469 // passed the allocated but uninitialized instance to construct. | 1510 // passed the allocated but uninitialized instance to construct. |
1470 // An instance closure may capture and access the receiver, but via the | 1511 // An instance closure may capture and access the receiver, but via the |
1471 // context and not via the first formal parameter. | 1512 // context and not via the first formal parameter. |
1472 // The first parameter of a factory is the TypeArguments vector of the type | 1513 // The first parameter of a factory is the TypeArguments vector of the type |
1473 // of the instance to be allocated. We name this hidden parameter 'this'. | 1514 // of the instance to be allocated. We name this hidden parameter 'this'. |
(...skipping 21 matching lines...) Expand all Loading... | |
1495 | 1536 |
1496 // If this is a constructor, initialize instance fields that have an | 1537 // If this is a constructor, initialize instance fields that have an |
1497 // explicit initializer expression. This has to be done before code | 1538 // explicit initializer expression. This has to be done before code |
1498 // for field initializer parameters are is generated. | 1539 // for field initializer parameters are is generated. |
1499 // NB: the instance field initializers have to be compiled before | 1540 // NB: the instance field initializers have to be compiled before |
1500 // the parameters are added to the scope, so that a parameter | 1541 // the parameters are added to the scope, so that a parameter |
1501 // name cannot shadow a name used in the field initializer expression. | 1542 // name cannot shadow a name used in the field initializer expression. |
1502 | 1543 |
1503 GrowableArray<FieldInitExpression> initializers; | 1544 GrowableArray<FieldInitExpression> initializers; |
1504 if (func.IsConstructor()) { | 1545 if (func.IsConstructor()) { |
1505 Class& cls = Class::Handle(func.owner()); | |
1506 ParseInitializedInstanceFields(cls, &initializers); | 1546 ParseInitializedInstanceFields(cls, &initializers); |
1507 } | 1547 } |
1508 | 1548 |
1509 // Now populate function scope with the formal parameters. | 1549 // Now populate function scope with the formal parameters. |
1510 AddFormalParamsToScope(¶ms, current_block_->scope); | 1550 AddFormalParamsToScope(¶ms, current_block_->scope); |
1511 | 1551 |
1512 // Now that the "this" parameter is in scope, we can generate the code | 1552 // Now that the "this" parameter is in scope, we can generate the code |
1513 // to strore the initializer expressions in the respective instance fields. | 1553 // to strore the initializer expressions in the respective instance fields. |
1514 // We do this before the field parameters and the initializers from the | 1554 // We do this before the field parameters and the initializers from the |
1515 // constuctor's initializer list get compiled. | 1555 // constuctor's initializer list get compiled. |
1516 if (initializers.length() > 0) { | 1556 if (initializers.length() > 0) { |
1517 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1557 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1518 for (int i = 0; i < initializers.length(); i++) { | 1558 for (int i = 0; i < initializers.length(); i++) { |
1519 const Field* field = initializers[i].inst_field; | 1559 const Field* field = initializers[i].inst_field; |
1520 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); | 1560 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); |
1521 AstNode* field_init = | 1561 AstNode* field_init = |
1522 new StoreInstanceFieldNode(field->token_index(), | 1562 new StoreInstanceFieldNode(field->token_index(), |
1523 instance, | 1563 instance, |
1524 *field, | 1564 *field, |
1525 initializers[i].expr); | 1565 initializers[i].expr); |
1526 current_block_->statements->Add(field_init); | 1566 current_block_->statements->Add(field_init); |
1527 } | 1567 } |
1528 } | 1568 } |
1529 | 1569 |
1530 // Turn formal field parameters into field initializers or report error | 1570 // Turn formal field parameters into field initializers or report error |
1531 // if the function is not a constructor | 1571 // if the function is not a constructor |
1532 if (params.has_field_initializer) { | 1572 if (params.has_field_initializer) { |
1533 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1573 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1534 Class& cls = Class::ZoneHandle(func.owner()); | |
1535 for (int i = 0; i < params.parameters->length(); i++) { | 1574 for (int i = 0; i < params.parameters->length(); i++) { |
1536 ParamDesc& param = (*params.parameters)[i]; | 1575 ParamDesc& param = (*params.parameters)[i]; |
1537 if (param.is_field_initializer) { | 1576 if (param.is_field_initializer) { |
1538 if (!func.IsConstructor()) { | 1577 if (!func.IsConstructor()) { |
1539 ErrorMsg(param.name_pos, | 1578 ErrorMsg(param.name_pos, |
1540 "field initializer only allowed in constructors"); | 1579 "field initializer only allowed in constructors"); |
1541 } | 1580 } |
1542 | 1581 |
1543 const String& field_name = *param.name; | 1582 const String& field_name = *param.name; |
1544 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); | 1583 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); |
(...skipping 10 matching lines...) Expand all Loading... | |
1555 ASSERT(p != NULL); | 1594 ASSERT(p != NULL); |
1556 AstNode* value = new LoadLocalNode(param.name_pos, *p); | 1595 AstNode* value = new LoadLocalNode(param.name_pos, *p); |
1557 AstNode* initializer = | 1596 AstNode* initializer = |
1558 new StoreInstanceFieldNode(param.name_pos, instance, field, value); | 1597 new StoreInstanceFieldNode(param.name_pos, instance, field, value); |
1559 current_block_->statements->Add(initializer); | 1598 current_block_->statements->Add(initializer); |
1560 } | 1599 } |
1561 } | 1600 } |
1562 } | 1601 } |
1563 | 1602 |
1564 if (func.IsConstructor()) { | 1603 if (func.IsConstructor()) { |
1565 Class& cls = Class::ZoneHandle(func.owner()); | 1604 ParseInitializers(cls); |
1566 bool initialized_check_needed = true; | |
1567 if (CurrentToken() == Token::kCOLON) { | |
1568 ConsumeToken(); | |
1569 LocalVariable* receiver = current_block_->scope->VariableAt(0); | |
1570 ASSERT(receiver != NULL); | |
1571 if ((CurrentToken() == Token::kTHIS) && | |
1572 ((LookaheadToken(1) == Token::kLPAREN) || | |
1573 ((LookaheadToken(1) == Token::kPERIOD) && | |
1574 (LookaheadToken(3) == Token::kLPAREN)))) { | |
1575 // Either we see this(...) or this.xxx(...) which is a | |
1576 // redirected constructor. We don't need to check whether | |
1577 // const fields are initialized. The other constructor will | |
1578 // guarantee that. | |
1579 initialized_check_needed = false; | |
1580 ParseConstructorRedirection(cls, receiver); | |
1581 } else { | |
1582 ParseInitializers(cls, receiver); | |
1583 } | |
1584 } | |
1585 if (initialized_check_needed) { | |
1586 CheckConstFieldsInitialized(cls); | |
1587 } | |
1588 } | 1605 } |
1589 | 1606 |
1590 if (current_block_->scope->function_level() > 0) { | 1607 if (current_block_->scope->function_level() > 0) { |
1591 // We are parsing, but not compiling, a local function. | 1608 // We are parsing, but not compiling, a local function. |
1592 // The instantiator may be required at run time for generic type checks or | 1609 // The instantiator may be required at run time for generic type checks or |
1593 // allocation of generic types. | 1610 // allocation of generic types. |
1594 if (current_class().IsParameterized() && | 1611 if (current_class().IsParameterized() && |
1595 (!current_function().is_static() || | 1612 (!current_function().is_static() || |
1596 current_function().IsInFactoryScope())) { | 1613 current_function().IsInFactoryScope())) { |
1597 // Make sure that the receiver of the enclosing instance function | 1614 // Make sure that the receiver of the enclosing instance function |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1645 level++; | 1662 level++; |
1646 } else if (CurrentToken() == Token::kRPAREN) { | 1663 } else if (CurrentToken() == Token::kRPAREN) { |
1647 level--; | 1664 level--; |
1648 } | 1665 } |
1649 ConsumeToken(); | 1666 ConsumeToken(); |
1650 } while ((level > 0) && (CurrentToken() != Token::kEOS)); | 1667 } while ((level > 0) && (CurrentToken() != Token::kEOS)); |
1651 } | 1668 } |
1652 | 1669 |
1653 | 1670 |
1654 void Parser::SkipInitializers() { | 1671 void Parser::SkipInitializers() { |
1655 if (CurrentToken() == Token::kSUPER) { | 1672 for (;;) { |
regis
2011/10/13 19:32:29
Same comment here about a do loop instead of a for
hausner
2011/10/13 20:24:09
And done.
| |
1673 if (CurrentToken() == Token::kSUPER) { | |
1674 ConsumeToken(); | |
1675 if (CurrentToken() == Token::kPERIOD) { | |
1676 ConsumeToken(); | |
1677 ExpectIdentifier("identifier expected"); | |
1678 } | |
1679 if (CurrentToken() != Token::kLPAREN) { | |
1680 ErrorMsg("'(' expected"); | |
1681 } | |
1682 SkipToMatchingParenthesis(); | |
1683 } else { | |
1684 SkipIf(Token::kTHIS); | |
1685 SkipIf(Token::kPERIOD); | |
1686 ExpectIdentifier("identifier expected"); | |
1687 ExpectToken(Token::kASSIGN); | |
1688 SetAllowFunctionLiterals(false); | |
1689 SkipExpr(); | |
1690 SetAllowFunctionLiterals(true); | |
1691 } | |
1692 if (CurrentToken() != Token::kCOMMA) { | |
1693 break; | |
1694 } | |
1656 ConsumeToken(); | 1695 ConsumeToken(); |
1657 if (CurrentToken() == Token::kPERIOD) { | |
1658 ConsumeToken(); | |
1659 ExpectIdentifier("identifier expected"); | |
1660 } | |
1661 if (CurrentToken() != Token::kLPAREN) { | |
1662 ErrorMsg("'(' expected"); | |
1663 } | |
1664 SkipToMatchingParenthesis(); | |
1665 } else { | |
1666 SkipIf(Token::kTHIS); | |
1667 SkipIf(Token::kPERIOD); | |
1668 ExpectIdentifier("identifier expected"); | |
1669 ExpectToken(Token::kASSIGN); | |
1670 SetAllowFunctionLiterals(false); | |
1671 SkipExpr(); | |
1672 SetAllowFunctionLiterals(true); | |
1673 } | |
1674 while (CurrentToken() == Token::kCOMMA) { | |
1675 ConsumeToken(); | |
1676 SkipIf(Token::kTHIS); | |
1677 SkipIf(Token::kPERIOD); | |
1678 ExpectIdentifier("instance field expected"); | |
1679 ExpectToken(Token::kASSIGN); | |
1680 SetAllowFunctionLiterals(false); | |
1681 SkipExpr(); | |
1682 SetAllowFunctionLiterals(true); | |
1683 } | 1696 } |
1684 } | 1697 } |
1685 | 1698 |
1686 | 1699 |
1687 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 1700 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
1688 ASSERT(CurrentToken() == Token::kIDENT); | 1701 ASSERT(CurrentToken() == Token::kIDENT); |
1689 if (!is_top_level_) { | 1702 if (!is_top_level_) { |
1690 bool local_ident = ResolveIdentInLocalScope(token_index_, | 1703 bool local_ident = ResolveIdentInLocalScope(token_index_, |
1691 *CurrentLiteral(), | 1704 *CurrentLiteral(), |
1692 NULL); | 1705 NULL); |
(...skipping 5289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6982 } | 6995 } |
6983 | 6996 |
6984 | 6997 |
6985 void Parser::SkipNestedExpr() { | 6998 void Parser::SkipNestedExpr() { |
6986 const bool saved_mode = SetAllowFunctionLiterals(true); | 6999 const bool saved_mode = SetAllowFunctionLiterals(true); |
6987 SkipExpr(); | 7000 SkipExpr(); |
6988 SetAllowFunctionLiterals(saved_mode); | 7001 SetAllowFunctionLiterals(saved_mode); |
6989 } | 7002 } |
6990 | 7003 |
6991 } // namespace dart | 7004 } // namespace dart |
OLD | NEW |