| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 3527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3538 // For instance fields, the expression is parsed when a constructor | 3538 // For instance fields, the expression is parsed when a constructor |
| 3539 // is compiled. | 3539 // is compiled. |
| 3540 // For static fields with very simple initializer expressions | 3540 // For static fields with very simple initializer expressions |
| 3541 // (e.g. a literal number or string), we optimize away the | 3541 // (e.g. a literal number or string), we optimize away the |
| 3542 // kImplicitStaticFinalGetter and initialize the field here. | 3542 // kImplicitStaticFinalGetter and initialize the field here. |
| 3543 // However, the class finalizer will check the value type for | 3543 // However, the class finalizer will check the value type for |
| 3544 // assignability once the declared field type can be resolved. If the | 3544 // assignability once the declared field type can be resolved. If the |
| 3545 // value is not assignable (assuming checked mode and disregarding actual | 3545 // value is not assignable (assuming checked mode and disregarding actual |
| 3546 // mode), the field value is reset and a kImplicitStaticFinalGetter is | 3546 // mode), the field value is reset and a kImplicitStaticFinalGetter is |
| 3547 // created at finalization time. | 3547 // created at finalization time. |
| 3548 if (field->has_static && (LookaheadToken(1) == Token::kSEMICOLON)) { | 3548 if (LookaheadToken(1) == Token::kSEMICOLON) { |
| 3549 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); | 3549 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); |
| 3550 } | 3550 } |
| 3551 SkipExpr(); | 3551 SkipExpr(); |
| 3552 } else { | 3552 } else { |
| 3553 // Static const and static final fields must have an initializer. | 3553 // Static const and static final fields must have an initializer. |
| 3554 // Static const fields are implicitly final. | 3554 // Static const fields are implicitly final. |
| 3555 if (field->has_static && field->has_final) { | 3555 if (field->has_static && field->has_final) { |
| 3556 ErrorMsg(field->name_pos, | 3556 ErrorMsg(field->name_pos, |
| 3557 "static %s field '%s' must have an initializer expression", | 3557 "static %s field '%s' must have an initializer expression", |
| 3558 field->has_const ? "const" : "final", | 3558 field->has_const ? "const" : "final", |
| 3559 field->name->ToCString()); | 3559 field->name->ToCString()); |
| 3560 } | 3560 } |
| 3561 } | 3561 } |
| 3562 | 3562 |
| 3563 // Create the field object. | 3563 // Create the field object. |
| 3564 class_field = Field::New(*field->name, | 3564 class_field = Field::New(*field->name, |
| 3565 field->has_static, | 3565 field->has_static, |
| 3566 field->has_final, | 3566 field->has_final, |
| 3567 field->has_const, | 3567 field->has_const, |
| 3568 current_class(), | 3568 current_class(), |
| 3569 field->name_pos); | 3569 field->name_pos); |
| 3570 class_field.set_type(*field->type); | 3570 class_field.set_type(*field->type); |
| 3571 class_field.set_has_initializer(has_initializer); | 3571 class_field.set_has_initializer(has_initializer); |
| 3572 members->AddField(class_field); | 3572 members->AddField(class_field); |
| 3573 field->field_ = &class_field; | 3573 field->field_ = &class_field; |
| 3574 if (field->metadata_pos >= 0) { | 3574 if (field->metadata_pos >= 0) { |
| 3575 library_.AddFieldMetadata(class_field, field->metadata_pos); | 3575 library_.AddFieldMetadata(class_field, field->metadata_pos); |
| 3576 } | 3576 } |
| 3577 | 3577 |
| 3578 // Start tracking types for fields with simple initializers in their |
| 3579 // definition. This avoids some of the overhead to track this at runtime |
| 3580 // and rules out many fields from being unnecessary unboxing candidates. |
| 3581 if (!field->has_static && has_initializer && has_simple_literal) { |
| 3582 class_field.RecordStore(init_value); |
| 3583 } |
| 3584 |
| 3578 // For static final fields (this includes static const fields), set value to | 3585 // For static final fields (this includes static const fields), set value to |
| 3579 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. | 3586 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. |
| 3580 if (field->has_static && has_initializer) { | 3587 if (field->has_static && has_initializer) { |
| 3581 class_field.set_value(init_value); | 3588 class_field.set_value(init_value); |
| 3582 if (!has_simple_literal) { | 3589 if (!has_simple_literal) { |
| 3583 String& getter_name = String::Handle(isolate(), | 3590 String& getter_name = String::Handle(isolate(), |
| 3584 Field::GetterSymbol(*field->name)); | 3591 Field::GetterSymbol(*field->name)); |
| 3585 getter = Function::New(getter_name, | 3592 getter = Function::New(getter_name, |
| 3586 RawFunction::kImplicitStaticFinalGetter, | 3593 RawFunction::kImplicitStaticFinalGetter, |
| 3587 field->has_static, | 3594 field->has_static, |
| (...skipping 7478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11066 void Parser::SkipQualIdent() { | 11073 void Parser::SkipQualIdent() { |
| 11067 ASSERT(IsIdentifier()); | 11074 ASSERT(IsIdentifier()); |
| 11068 ConsumeToken(); | 11075 ConsumeToken(); |
| 11069 if (CurrentToken() == Token::kPERIOD) { | 11076 if (CurrentToken() == Token::kPERIOD) { |
| 11070 ConsumeToken(); // Consume the kPERIOD token. | 11077 ConsumeToken(); // Consume the kPERIOD token. |
| 11071 ExpectIdentifier("identifier expected after '.'"); | 11078 ExpectIdentifier("identifier expected after '.'"); |
| 11072 } | 11079 } |
| 11073 } | 11080 } |
| 11074 | 11081 |
| 11075 } // namespace dart | 11082 } // namespace dart |
| OLD | NEW |