Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: runtime/vm/ast.cc

Issue 10849004: Fix super getter/setter (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698