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

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

Issue 11669015: Turn compile time errors related to missing getters and setters into invocation (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 12 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 #include "vm/resolver.h"
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 286
287 const Instance* ClosureNode::EvalConstExpr() const { 287 const Instance* ClosureNode::EvalConstExpr() const {
288 if (function().IsImplicitStaticClosureFunction()) { 288 if (function().IsImplicitStaticClosureFunction()) {
289 // Return a value that represents an instance. Only the type is relevant. 289 // Return a value that represents an instance. Only the type is relevant.
290 return &Instance::Handle(); 290 return &Instance::Handle();
291 } 291 }
292 return NULL; 292 return NULL;
293 } 293 }
294 294
295 295
296 AstNode* ClosureNode::MakeAssignmentNode(AstNode* rhs) {
297 if (scope() == NULL) {
298 // This is an implicit closure node created because a static getter was not
299 // found. Change the getter into a setter. If it does not exist,
300 // noSuchMethod will be called.
301 return new StaticSetterNode(token_pos(),
302 receiver(),
303 Class::ZoneHandle(function().Owner()),
304 String::ZoneHandle(function().name()),
305 rhs);
306 }
307 return NULL;
308 }
309
310
296 const char* UnaryOpNode::Name() const { 311 const char* UnaryOpNode::Name() const {
297 return Token::Str(kind_); 312 return Token::Str(kind_);
298 } 313 }
299 314
300 315
301 const char* JumpNode::Name() const { 316 const char* JumpNode::Name() const {
302 return Token::Str(kind_); 317 return Token::Str(kind_);
303 } 318 }
304 319
305 320
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { 353 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) {
339 return new StoreIndexedNode(token_pos(), array(), index_expr(), 354 return new StoreIndexedNode(token_pos(), array(), index_expr(),
340 rhs, super_class()); 355 rhs, super_class());
341 } 356 }
342 357
343 358
344 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { 359 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
345 const String& setter_name = String::Handle(Field::SetterName(field_name())); 360 const String& setter_name = String::Handle(Field::SetterName(field_name()));
346 361
347 if (is_super_getter_) { 362 if (is_super_getter_) {
348 // Resolve the (dynamic) setter method.
349 ASSERT(receiver() != NULL); 363 ASSERT(receiver() != NULL);
350 const Function& super_setter = Function::ZoneHandle( 364 // If the static setter is not found in the superclass, noSuchMethod will be
351 Resolver::ResolveDynamicAnyArgs(cls(), setter_name)); 365 // called at runtime.
352 if (!super_setter.IsNull()) { 366 return new StaticSetterNode(token_pos(),
353 return new StaticSetterNode(token_pos(), 367 receiver(),
354 receiver(), 368 cls(),
355 cls(), 369 field_name(),
356 field_name(), 370 rhs);
357 rhs); 371 }
358 } 372 const Function& setter =
359 // If setter is found in the superclass, do not turn this into an 373 Function::ZoneHandle(cls().LookupStaticFunction(setter_name));
360 // instance setter resolved at runtime, since a super getter/setter 374 if (!setter.IsNull()) {
361 // explicitly refers to the static superclass of the enclosing function. 375 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
362 return NULL; 376 }
363 } else { 377 // Could not find a static setter. Look for a field.
364 const Function& setter = 378 // Access to a lazily initialized static field that has not yet been
365 Function::ZoneHandle(cls().LookupStaticFunction(setter_name)); 379 // initialized is compiled to a static implicit getter.
366 if (!setter.IsNull()) { 380 // A setter may not exist for such a field.
381 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name()));
382 if (!field.IsNull()) {
383 if (field.is_final()) {
384 // Attempting to assign to a final variable will cause a NoSuchMethodError
385 // to be thrown. Change static getter to non-existent static setter in
386 // order to trigger the throw at runtime.
367 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); 387 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
368 } 388 }
369 // Could not find a static setter. Look for a field.
370 // Access to a lazily initialized static field that has not yet been
371 // initialized is compiled to a static implicit getter.
372 // A setter may not exist for such a field.
373 const Field& field =
374 Field::ZoneHandle(cls().LookupStaticField(field_name()));
375 if (!field.IsNull()) {
376 if (field.is_final()) {
377 return NULL;
378 }
379 #if defined(DEBUG) 389 #if defined(DEBUG)
380 const String& getter_name = 390 const String& getter_name = String::Handle(Field::GetterName(field_name()));
381 String::Handle(Field::GetterName(field_name())); 391 const Function& getter =
382 const Function& getter = 392 Function::Handle(cls().LookupStaticFunction(getter_name));
383 Function::ZoneHandle(cls().LookupStaticFunction(getter_name)); 393 ASSERT(!getter.IsNull() &&
384 ASSERT(!getter.IsNull() && 394 (getter.kind() == RawFunction::kConstImplicitGetter));
385 (getter.kind() == RawFunction::kConstImplicitGetter));
386 #endif 395 #endif
387 return new StoreStaticFieldNode(token_pos(), field, rhs); 396 return new StoreStaticFieldNode(token_pos(), field, rhs);
388 }
389 // Didn't find a static setter or a static field.
390 // If this static getter is in an instance function where
391 // a receiver is available, we turn this static getter
392 // into an instance setter (and will get an error at runtime if an
393 // instance setter cannot be found either).
394 if (receiver() != NULL) {
395 return new InstanceSetterNode(token_pos(),
396 receiver(),
397 field_name(),
398 rhs);
399 }
400 return NULL;
401 } 397 }
398 // Didn't find a static setter or a static field.
399 // If this static getter is in an instance function where
400 // a receiver is available, we turn this static getter
401 // into an instance setter (and will get an error at runtime if an
402 // instance setter cannot be found either).
403 if (receiver() != NULL) {
404 return new InstanceSetterNode(token_pos(), receiver(), field_name(), rhs);
405 }
406 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
402 } 407 }
403 408
404 409
405 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { 410 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) {
406 // Return this node if it represents a 'throw NoSuchMethodError' indicating 411 // Return this node if it represents a 'throw NoSuchMethodError' indicating
407 // that a getter was not found, otherwise return null. 412 // that a getter was not found, otherwise return null.
408 const Class& cls = Class::Handle(function().Owner()); 413 const Class& cls = Class::Handle(function().Owner());
409 const String& cls_name = String::Handle(cls.Name()); 414 const String& cls_name = String::Handle(cls.Name());
410 const String& func_name = String::Handle(function().name()); 415 const String& func_name = String::Handle(function().name());
411 const String& error_cls_name = String::Handle(Symbols::NoSuchMethodError()); 416 const String& error_cls_name = String::Handle(Symbols::NoSuchMethodError());
(...skipping 19 matching lines...) Expand all
431 if (result.IsError() || result.IsNull()) { 436 if (result.IsError() || result.IsNull()) {
432 // TODO(turnidge): We could get better error messages by returning 437 // TODO(turnidge): We could get better error messages by returning
433 // the Error object directly to the parser. This will involve 438 // the Error object directly to the parser. This will involve
434 // replumbing all of the EvalConstExpr methods. 439 // replumbing all of the EvalConstExpr methods.
435 return NULL; 440 return NULL;
436 } 441 }
437 return &Instance::ZoneHandle(Instance::Cast(result).raw()); 442 return &Instance::ZoneHandle(Instance::Cast(result).raw());
438 } 443 }
439 444
440 } // namespace dart 445 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698