Chromium Code Reviews| 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 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1356 initializers->Add(initializer); | 1356 initializers->Add(initializer); |
| 1357 } | 1357 } |
| 1358 } | 1358 } |
| 1359 SetPosition(saved_pos); | 1359 SetPosition(saved_pos); |
| 1360 } | 1360 } |
| 1361 | 1361 |
| 1362 | 1362 |
| 1363 void Parser::ParseInitializers(const Class& cls) { | 1363 void Parser::ParseInitializers(const Class& cls) { |
| 1364 TRACE_PARSER("ParseInitializers"); | 1364 TRACE_PARSER("ParseInitializers"); |
| 1365 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1365 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1366 bool super_init_seen = false; | 1366 AstNode* super_init_statement = NULL; |
| 1367 if (CurrentToken() == Token::kCOLON) { | 1367 if (CurrentToken() == Token::kCOLON) { |
| 1368 if ((LookaheadToken(1) == Token::kTHIS) && | 1368 if ((LookaheadToken(1) == Token::kTHIS) && |
| 1369 ((LookaheadToken(2) == Token::kLPAREN) || | 1369 ((LookaheadToken(2) == Token::kLPAREN) || |
| 1370 ((LookaheadToken(2) == Token::kPERIOD) && | 1370 ((LookaheadToken(2) == Token::kPERIOD) && |
| 1371 (LookaheadToken(4) == Token::kLPAREN)))) { | 1371 (LookaheadToken(4) == Token::kLPAREN)))) { |
| 1372 // Either we see this(...) or this.xxx(...) which is a | 1372 // Either we see this(...) or this.xxx(...) which is a |
| 1373 // redirected constructor. We don't need to check whether | 1373 // redirected constructor. We don't need to check whether |
| 1374 // const fields are initialized. The other constructor will | 1374 // const fields are initialized. The other constructor will |
| 1375 // guarantee that. | 1375 // guarantee that. |
| 1376 ConsumeToken(); // Colon. | 1376 ConsumeToken(); // Colon. |
| 1377 ParseConstructorRedirection(cls, receiver); | 1377 ParseConstructorRedirection(cls, receiver); |
| 1378 return; | 1378 return; |
| 1379 } | 1379 } |
| 1380 | 1380 |
| 1381 do { | 1381 do { |
| 1382 ConsumeToken(); // Colon or comma. | 1382 ConsumeToken(); // Colon or comma. |
| 1383 AstNode* init_statement = NULL; | |
| 1384 if (CurrentToken() == Token::kSUPER) { | 1383 if (CurrentToken() == Token::kSUPER) { |
| 1385 if (super_init_seen) { | 1384 if (super_init_statement != NULL) { |
| 1386 ErrorMsg("Duplicate call to super constructor"); | 1385 ErrorMsg("Duplicate call to super constructor"); |
| 1387 } | 1386 } |
| 1388 init_statement = ParseSuperInitializer(cls, receiver); | 1387 super_init_statement = ParseSuperInitializer(cls, receiver); |
| 1389 super_init_seen = true; | |
| 1390 } else { | 1388 } else { |
| 1391 init_statement = ParseInitializer(cls, receiver); | 1389 AstNode* init_statement = ParseInitializer(cls, receiver); |
| 1390 current_block_->statements->Add(init_statement); | |
| 1392 } | 1391 } |
| 1393 current_block_->statements->Add(init_statement); | |
| 1394 } while (CurrentToken() == Token::kCOMMA); | 1392 } while (CurrentToken() == Token::kCOMMA); |
| 1395 } | 1393 } |
| 1396 | 1394 |
| 1397 // Generate implicit super() if we haven't seen an explicit super call | 1395 if (super_init_statement != NULL) { |
| 1398 // or constructor redirection. | 1396 // TODO(hausner): Move explicit supercall to the end of the initializer |
|
regis
2011/10/24 22:39:19
Is this TODO still needed?
| |
| 1399 // Omit the implicit super() if there is no super class (i.e. | 1397 // list to avoid executing constructor code on partially initialized |
| 1400 // we're not compiling class Object), or if the super class is an | 1398 // objects. Issue 4995181. |
| 1401 // artificially generated "wrapper class" that has no constructor. | 1399 current_block_->statements->Add(super_init_statement); |
| 1402 if (!super_init_seen) { | 1400 } else { |
| 1401 // Generate implicit super() if we haven't seen an explicit super call | |
| 1402 // or constructor redirection. | |
| 1403 GenerateSuperInitializerCall(cls, receiver); | 1403 GenerateSuperInitializerCall(cls, receiver); |
| 1404 } | 1404 } |
| 1405 | 1405 |
| 1406 CheckConstFieldsInitialized(cls); | 1406 CheckConstFieldsInitialized(cls); |
| 1407 } | 1407 } |
| 1408 | 1408 |
| 1409 | 1409 |
| 1410 void Parser::ParseConstructorRedirection(const Class& cls, | 1410 void Parser::ParseConstructorRedirection(const Class& cls, |
| 1411 LocalVariable* receiver) { | 1411 LocalVariable* receiver) { |
| 1412 ASSERT(CurrentToken() == Token::kTHIS); | 1412 ASSERT(CurrentToken() == Token::kTHIS); |
| (...skipping 5592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7005 } | 7005 } |
| 7006 | 7006 |
| 7007 | 7007 |
| 7008 void Parser::SkipNestedExpr() { | 7008 void Parser::SkipNestedExpr() { |
| 7009 const bool saved_mode = SetAllowFunctionLiterals(true); | 7009 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7010 SkipExpr(); | 7010 SkipExpr(); |
| 7011 SetAllowFunctionLiterals(saved_mode); | 7011 SetAllowFunctionLiterals(saved_mode); |
| 7012 } | 7012 } |
| 7013 | 7013 |
| 7014 } // namespace dart | 7014 } // namespace dart |
| OLD | NEW |