| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 2143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 ErrorMsg(field_pos, "unresolved reference to instance field '%s'", | 2154 ErrorMsg(field_pos, "unresolved reference to instance field '%s'", |
| 2155 field_name.ToCString()); | 2155 field_name.ToCString()); |
| 2156 } | 2156 } |
| 2157 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); | 2157 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); |
| 2158 AstNode* instance = new LoadLocalNode(field_pos, receiver); | 2158 AstNode* instance = new LoadLocalNode(field_pos, receiver); |
| 2159 EnsureExpressionTemp(); | 2159 EnsureExpressionTemp(); |
| 2160 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); | 2160 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); |
| 2161 } | 2161 } |
| 2162 | 2162 |
| 2163 | 2163 |
| 2164 void Parser::CheckConstFieldsInitialized(const Class& cls) { | 2164 void Parser::CheckFieldsInitialized(const Class& cls) { |
| 2165 const Array& fields = Array::Handle(cls.fields()); | 2165 const Array& fields = Array::Handle(cls.fields()); |
| 2166 Field& field = Field::Handle(); | 2166 Field& field = Field::Handle(); |
| 2167 SequenceNode* initializers = current_block_->statements; | 2167 SequenceNode* initializers = current_block_->statements; |
| 2168 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 2168 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
| 2169 field ^= fields.At(field_num); | 2169 field ^= fields.At(field_num); |
| 2170 if (field.is_static()) { | 2170 if (field.is_static()) { |
| 2171 continue; | 2171 continue; |
| 2172 } | 2172 } |
| 2173 | 2173 |
| 2174 bool found = false; | 2174 bool found = false; |
| 2175 for (int i = 0; i < initializers->length(); i++) { | 2175 for (int i = 0; i < initializers->length(); i++) { |
| 2176 found = false; | 2176 found = false; |
| 2177 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { | 2177 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { |
| 2178 StoreInstanceFieldNode* initializer = | 2178 StoreInstanceFieldNode* initializer = |
| 2179 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); | 2179 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); |
| 2180 if (initializer->field().raw() == field.raw()) { | 2180 if (initializer->field().raw() == field.raw()) { |
| 2181 found = true; | 2181 found = true; |
| 2182 break; | 2182 break; |
| 2183 } | 2183 } |
| 2184 } | 2184 } |
| 2185 } | 2185 } |
| 2186 | 2186 |
| 2187 if (found) continue; | 2187 if (found) continue; |
| 2188 | 2188 |
| 2189 if (field.is_final()) { | 2189 field.UpdateCid(kNullCid); |
| 2190 ErrorMsg("final field '%s' not initialized", | 2190 field.UpdateLength(Field::kNoFixedLength); |
| 2191 String::Handle(field.name()).ToCString()); | |
| 2192 } else { | |
| 2193 field.UpdateCid(kNullCid); | |
| 2194 field.UpdateLength(Field::kNoFixedLength); | |
| 2195 } | |
| 2196 } | 2191 } |
| 2197 } | 2192 } |
| 2198 | 2193 |
| 2199 | 2194 |
| 2200 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2195 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
| 2201 // Only use this function if the initialized field originates | 2196 // Only use this function if the initialized field originates |
| 2202 // from a different class. We need to save and restore current | 2197 // from a different class. We need to save and restore current |
| 2203 // class, library, and token stream (script). | 2198 // class, library, and token stream (script). |
| 2204 ASSERT(current_class().raw() != field.origin()); | 2199 ASSERT(current_class().raw() != field.origin()); |
| 2205 const Class& saved_class = Class::Handle(current_class().raw()); | 2200 const Class& saved_class = Class::Handle(current_class().raw()); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2317 init_statement = ParseInitializer(cls, receiver, initialized_fields); | 2312 init_statement = ParseInitializer(cls, receiver, initialized_fields); |
| 2318 } | 2313 } |
| 2319 current_block_->statements->Add(init_statement); | 2314 current_block_->statements->Add(init_statement); |
| 2320 } while (CurrentToken() == Token::kCOMMA); | 2315 } while (CurrentToken() == Token::kCOMMA); |
| 2321 } | 2316 } |
| 2322 if (!super_init_seen) { | 2317 if (!super_init_seen) { |
| 2323 // Generate implicit super() if we haven't seen an explicit super call | 2318 // Generate implicit super() if we haven't seen an explicit super call |
| 2324 // or constructor redirection. | 2319 // or constructor redirection. |
| 2325 GenerateSuperConstructorCall(cls, receiver, NULL); | 2320 GenerateSuperConstructorCall(cls, receiver, NULL); |
| 2326 } | 2321 } |
| 2327 CheckConstFieldsInitialized(cls); | 2322 CheckFieldsInitialized(cls); |
| 2328 } | 2323 } |
| 2329 | 2324 |
| 2330 | 2325 |
| 2331 void Parser::ParseConstructorRedirection(const Class& cls, | 2326 void Parser::ParseConstructorRedirection(const Class& cls, |
| 2332 LocalVariable* receiver) { | 2327 LocalVariable* receiver) { |
| 2333 TRACE_PARSER("ParseConstructorRedirection"); | 2328 TRACE_PARSER("ParseConstructorRedirection"); |
| 2334 ExpectToken(Token::kCOLON); | 2329 ExpectToken(Token::kCOLON); |
| 2335 ASSERT(CurrentToken() == Token::kTHIS); | 2330 ASSERT(CurrentToken() == Token::kTHIS); |
| 2336 const intptr_t call_pos = TokenPos(); | 2331 const intptr_t call_pos = TokenPos(); |
| 2337 ConsumeToken(); | 2332 ConsumeToken(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2431 LocalVariable* param = new LocalVariable( | 2426 LocalVariable* param = new LocalVariable( |
| 2432 ctor_pos, | 2427 ctor_pos, |
| 2433 String::ZoneHandle(func.ParameterNameAt(i)), | 2428 String::ZoneHandle(func.ParameterNameAt(i)), |
| 2434 Type::ZoneHandle(Type::DynamicType())); | 2429 Type::ZoneHandle(Type::DynamicType())); |
| 2435 current_block_->scope->AddVariable(param); | 2430 current_block_->scope->AddVariable(param); |
| 2436 forwarding_args->Add(new LoadLocalNode(ctor_pos, param)); | 2431 forwarding_args->Add(new LoadLocalNode(ctor_pos, param)); |
| 2437 } | 2432 } |
| 2438 } | 2433 } |
| 2439 | 2434 |
| 2440 GenerateSuperConstructorCall(current_class(), receiver, forwarding_args); | 2435 GenerateSuperConstructorCall(current_class(), receiver, forwarding_args); |
| 2441 CheckConstFieldsInitialized(current_class()); | 2436 CheckFieldsInitialized(current_class()); |
| 2442 | 2437 |
| 2443 // Empty constructor body. | 2438 // Empty constructor body. |
| 2444 SequenceNode* statements = CloseBlock(); | 2439 SequenceNode* statements = CloseBlock(); |
| 2445 return statements; | 2440 return statements; |
| 2446 } | 2441 } |
| 2447 | 2442 |
| 2448 | 2443 |
| 2449 void Parser::CheckRecursiveInvocation() { | 2444 void Parser::CheckRecursiveInvocation() { |
| 2450 const GrowableObjectArray& pending_functions = | 2445 const GrowableObjectArray& pending_functions = |
| 2451 GrowableObjectArray::Handle( | 2446 GrowableObjectArray::Handle( |
| (...skipping 8172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10624 void Parser::SkipQualIdent() { | 10619 void Parser::SkipQualIdent() { |
| 10625 ASSERT(IsIdentifier()); | 10620 ASSERT(IsIdentifier()); |
| 10626 ConsumeToken(); | 10621 ConsumeToken(); |
| 10627 if (CurrentToken() == Token::kPERIOD) { | 10622 if (CurrentToken() == Token::kPERIOD) { |
| 10628 ConsumeToken(); // Consume the kPERIOD token. | 10623 ConsumeToken(); // Consume the kPERIOD token. |
| 10629 ExpectIdentifier("identifier expected after '.'"); | 10624 ExpectIdentifier("identifier expected after '.'"); |
| 10630 } | 10625 } |
| 10631 } | 10626 } |
| 10632 | 10627 |
| 10633 } // namespace dart | 10628 } // namespace dart |
| OLD | NEW |