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/ast.h" | 5 #include "vm/ast.h" |
6 #include "vm/compiler.h" | 6 #include "vm/compiler.h" |
7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
10 #include "vm/resolver.h" | |
10 | 11 |
11 | 12 |
12 namespace dart { | 13 namespace dart { |
13 | 14 |
14 #define DEFINE_VISIT_FUNCTION(type, name) \ | 15 #define DEFINE_VISIT_FUNCTION(type, name) \ |
15 void type::Visit(AstNodeVisitor* visitor) { \ | 16 void type::Visit(AstNodeVisitor* visitor) { \ |
16 visitor->Visit##type(this); \ | 17 visitor->Visit##type(this); \ |
17 } | 18 } |
18 NODE_LIST(DEFINE_VISIT_FUNCTION) | 19 NODE_LIST(DEFINE_VISIT_FUNCTION) |
19 #undef DEFINE_VISIT_FUNCTION | 20 #undef DEFINE_VISIT_FUNCTION |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 | 316 |
316 | 317 |
317 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { | 318 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { |
318 return new StoreIndexedNode(token_pos(), array(), index_expr(), rhs); | 319 return new StoreIndexedNode(token_pos(), array(), index_expr(), rhs); |
319 } | 320 } |
320 | 321 |
321 | 322 |
322 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { | 323 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { |
323 // If no setter exist, set the field directly. | 324 // If no setter exist, set the field directly. |
324 const String& setter_name = String::Handle(Field::SetterName(field_name())); | 325 const String& setter_name = String::Handle(Field::SetterName(field_name())); |
325 const Function& setter = | 326 |
326 Function::ZoneHandle(cls().LookupStaticFunction(setter_name)); | 327 if (is_super_getter_) { |
srdjan
2012/08/08 16:44:34
Add brief comment what is going on.
hausner
2012/08/08 17:42:02
Done.
| |
327 if (setter.IsNull()) { | 328 ASSERT(receiver() != NULL); |
328 const Field& field = Field::ZoneHandle( | 329 const Function& super_setter = Function::ZoneHandle( |
329 cls().LookupStaticField(field_name())); | 330 Resolver::ResolveDynamicAnyParams(cls(), setter_name)); |
330 if (field.IsNull()) { | 331 if (!super_setter.IsNull()) { |
331 // A static getter is declared, but no setter and no field. | 332 return new StaticSetterNode(token_pos(), |
332 if (receiver() != NULL) { | 333 receiver(), |
333 return new InstanceSetterNode(token_pos(), | 334 cls(), |
334 receiver(), | 335 field_name(), |
335 field_name(), | 336 rhs); |
336 rhs); | |
337 } | |
338 return NULL; | |
339 } | 337 } |
338 return NULL; | |
339 } else { | |
340 const Function& setter = | |
341 Function::ZoneHandle(cls().LookupStaticFunction(setter_name)); | |
342 if (!setter.IsNull()) { | |
343 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | |
344 } | |
345 // Could not find a static setter. Look for a field. | |
340 // Access to a lazily initialized static field that has not yet been | 346 // Access to a lazily initialized static field that has not yet been |
341 // initialized is compiled to a static implicit getter. | 347 // initialized is compiled to a static implicit getter. |
342 // A setter may not exist for such a field. | 348 // A setter may not exist for such a field. |
349 const Field& field = | |
350 Field::ZoneHandle(cls().LookupStaticField(field_name())); | |
351 if (!field.IsNull()) { | |
343 #if defined(DEBUG) | 352 #if defined(DEBUG) |
344 const String& getter_name = String::Handle(Field::GetterName(field_name())); | 353 const String& getter_name = |
345 const Function& getter = | 354 String::Handle(Field::GetterName(field_name())); |
346 Function::ZoneHandle(cls().LookupStaticFunction(getter_name)); | 355 const Function& getter = |
347 ASSERT(!getter.IsNull() && | 356 Function::ZoneHandle(cls().LookupStaticFunction(getter_name)); |
348 (getter.kind() == RawFunction::kConstImplicitGetter)); | 357 ASSERT(!getter.IsNull() && |
358 (getter.kind() == RawFunction::kConstImplicitGetter)); | |
349 #endif | 359 #endif |
350 return new StoreStaticFieldNode(token_pos(), field, rhs); | 360 return new StoreStaticFieldNode(token_pos(), field, rhs); |
351 } else { | 361 } |
352 return new StaticSetterNode(token_pos(), cls(), field_name(), rhs); | 362 // Didn't find a static setter or a static field. |
363 // If this static getter is in an instance function where | |
364 // a receiver is available, we turn this static getter | |
365 // into an instance setter (and will get an error at runtime if an | |
366 // instanse setter cannot be found either). | |
srdjan
2012/08/08 16:44:34
s/instanse/instance/
hausner
2012/08/08 17:42:02
Done.
| |
367 if (receiver() != NULL) { | |
368 return new InstanceSetterNode(token_pos(), | |
369 receiver(), | |
370 field_name(), | |
371 rhs); | |
372 } | |
373 return NULL; | |
353 } | 374 } |
354 } | 375 } |
355 | 376 |
356 | 377 |
357 const Instance* StaticGetterNode::EvalConstExpr() const { | 378 const Instance* StaticGetterNode::EvalConstExpr() const { |
358 const String& getter_name = | 379 const String& getter_name = |
359 String::Handle(Field::GetterName(this->field_name())); | 380 String::Handle(Field::GetterName(this->field_name())); |
360 const Function& getter_func = | 381 const Function& getter_func = |
361 Function::Handle(this->cls().LookupStaticFunction(getter_name)); | 382 Function::Handle(this->cls().LookupStaticFunction(getter_name)); |
362 if (getter_func.IsNull() || !getter_func.is_const()) { | 383 if (getter_func.IsNull() || !getter_func.is_const()) { |
363 return NULL; | 384 return NULL; |
364 } | 385 } |
365 GrowableArray<const Object*> arguments; | 386 GrowableArray<const Object*> arguments; |
366 const Array& kNoArgumentNames = Array::Handle(); | 387 const Array& kNoArgumentNames = Array::Handle(); |
367 const Object& result = | 388 const Object& result = |
368 Object::Handle(DartEntry::InvokeStatic(getter_func, | 389 Object::Handle(DartEntry::InvokeStatic(getter_func, |
369 arguments, | 390 arguments, |
370 kNoArgumentNames)); | 391 kNoArgumentNames)); |
371 if (result.IsError() || result.IsNull()) { | 392 if (result.IsError() || result.IsNull()) { |
372 // TODO(turnidge): We could get better error messages by returning | 393 // TODO(turnidge): We could get better error messages by returning |
373 // the Error object directly to the parser. This will involve | 394 // the Error object directly to the parser. This will involve |
374 // replumbing all of the EvalConstExpr methods. | 395 // replumbing all of the EvalConstExpr methods. |
375 return NULL; | 396 return NULL; |
376 } | 397 } |
377 return &Instance::ZoneHandle(Instance::Cast(result).raw()); | 398 return &Instance::ZoneHandle(Instance::Cast(result).raw()); |
378 } | 399 } |
379 | 400 |
380 } // namespace dart | 401 } // namespace dart |
OLD | NEW |