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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/ast.h ('k') | runtime/vm/ast_printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/log.h" 9 #include "vm/log.h"
10 #include "vm/object_store.h" 10 #include "vm/object_store.h"
11 #include "vm/resolver.h" 11 #include "vm/resolver.h"
12 12
13 13
14 namespace dart { 14 namespace dart {
15 15
16 #define DEFINE_VISIT_FUNCTION(BaseName) \ 16 #define DEFINE_VISIT_FUNCTION(BaseName) \
17 void BaseName##Node::Visit(AstNodeVisitor* visitor) { \ 17 void BaseName##Node::Visit(AstNodeVisitor* visitor) { \
18 visitor->Visit##BaseName##Node(this); \ 18 visitor->Visit##BaseName##Node(this); \
19 } 19 }
20 20
21 FOR_EACH_NODE(DEFINE_VISIT_FUNCTION) 21 FOR_EACH_NODE(DEFINE_VISIT_FUNCTION)
22 #undef DEFINE_VISIT_FUNCTION 22 #undef DEFINE_VISIT_FUNCTION
23 23
24 24
25 #define DEFINE_NAME_FUNCTION(BaseName) \ 25 #define DEFINE_NAME_FUNCTION(BaseName) \
26 const char* BaseName##Node::Name() const { \ 26 const char* BaseName##Node::Name() const { return #BaseName; }
27 return #BaseName; \
28 }
29 27
30 FOR_EACH_NODE(DEFINE_NAME_FUNCTION) 28 FOR_EACH_NODE(DEFINE_NAME_FUNCTION)
31 #undef DEFINE_NAME_FUNCTION 29 #undef DEFINE_NAME_FUNCTION
32 30
33 31
34 const Field* AstNode::MayCloneField(const Field& value) { 32 const Field* AstNode::MayCloneField(const Field& value) {
35 if (Compiler::IsBackgroundCompilation() || 33 if (Compiler::IsBackgroundCompilation() ||
36 FLAG_force_clone_compiler_objects) { 34 FLAG_force_clone_compiler_objects) {
37 return &Field::ZoneHandle(value.CloneFromOriginal()); 35 return &Field::ZoneHandle(value.CloneFromOriginal());
38 } else { 36 } else {
39 ASSERT(value.IsZoneHandle()); 37 ASSERT(value.IsZoneHandle());
40 return &value; 38 return &value;
41 } 39 }
42 } 40 }
43 41
44 42
45 // A visitor class to collect all the nodes (including children) into an 43 // A visitor class to collect all the nodes (including children) into an
46 // array. 44 // array.
47 class AstNodeCollector : public AstNodeVisitor { 45 class AstNodeCollector : public AstNodeVisitor {
48 public: 46 public:
49 explicit AstNodeCollector(GrowableArray<AstNode*>* nodes) 47 explicit AstNodeCollector(GrowableArray<AstNode*>* nodes) : nodes_(nodes) {}
50 : nodes_(nodes) { }
51 48
52 #define DEFINE_VISITOR_FUNCTION(BaseName) \ 49 #define DEFINE_VISITOR_FUNCTION(BaseName) \
53 virtual void Visit##BaseName##Node(BaseName##Node* node) { \ 50 virtual void Visit##BaseName##Node(BaseName##Node* node) { \
54 nodes_->Add(node); \ 51 nodes_->Add(node); \
55 node->VisitChildren(this); \ 52 node->VisitChildren(this); \
56 } 53 }
57 54
58 FOR_EACH_NODE(DEFINE_VISITOR_FUNCTION) 55 FOR_EACH_NODE(DEFINE_VISITOR_FUNCTION)
59 #undef DEFINE_VISITOR_FUNCTION 56 #undef DEFINE_VISITOR_FUNCTION
60 57
61 private: 58 private:
62 GrowableArray<AstNode*>* nodes_; 59 GrowableArray<AstNode*>* nodes_;
63 DISALLOW_COPY_AND_ASSIGN(AstNodeCollector); 60 DISALLOW_COPY_AND_ASSIGN(AstNodeCollector);
64 }; 61 };
65 62
66 63
67 void SequenceNode::CollectAllNodes(GrowableArray<AstNode*>* nodes) { 64 void SequenceNode::CollectAllNodes(GrowableArray<AstNode*>* nodes) {
68 AstNodeCollector node_collector(nodes); 65 AstNodeCollector node_collector(nodes);
69 this->Visit(&node_collector); 66 this->Visit(&node_collector);
70 } 67 }
71 68
72 69
73 void SequenceNode::VisitChildren(AstNodeVisitor* visitor) const { 70 void SequenceNode::VisitChildren(AstNodeVisitor* visitor) const {
74 for (intptr_t i = 0; i < this->length(); i++) { 71 for (intptr_t i = 0; i < this->length(); i++) {
75 NodeAt(i)->Visit(visitor); 72 NodeAt(i)->Visit(visitor);
76 } 73 }
77 } 74 }
78 75
79 76
80 void SequenceNode::Add(AstNode* node) { 77 void SequenceNode::Add(AstNode* node) {
81 if (node->IsReturnNode()) { 78 if (node->IsReturnNode()) {
82 node->AsReturnNode()->set_scope(scope()); 79 node->AsReturnNode()->set_scope(scope());
83 } 80 }
84 nodes_.Add(node); 81 nodes_.Add(node);
85 } 82 }
86 83
87 84
88 void PrimaryNode::VisitChildren(AstNodeVisitor* visitor) const { 85 void PrimaryNode::VisitChildren(AstNodeVisitor* visitor) const {}
89 }
90 86
91 87
92 void ArgumentListNode::VisitChildren(AstNodeVisitor* visitor) const { 88 void ArgumentListNode::VisitChildren(AstNodeVisitor* visitor) const {
93 for (intptr_t i = 0; i < this->length(); i++) { 89 for (intptr_t i = 0; i < this->length(); i++) {
94 NodeAt(i)->Visit(visitor); 90 NodeAt(i)->Visit(visitor);
95 } 91 }
96 } 92 }
97 93
98 94
99 LetNode::LetNode(TokenPosition token_pos) 95 LetNode::LetNode(TokenPosition token_pos)
100 : AstNode(token_pos), 96 : AstNode(token_pos), vars_(1), initializers_(1), nodes_(1) {}
101 vars_(1),
102 initializers_(1),
103 nodes_(1) { }
104 97
105 98
106 LocalVariable* LetNode::AddInitializer(AstNode* node) { 99 LocalVariable* LetNode::AddInitializer(AstNode* node) {
107 Thread* thread = Thread::Current(); 100 Thread* thread = Thread::Current();
108 Zone* zone = thread->zone(); 101 Zone* zone = thread->zone();
109 initializers_.Add(node); 102 initializers_.Add(node);
110 char name[64]; 103 char name[64];
111 OS::SNPrint(name, sizeof(name), ":lt%s_%" Pd "", 104 OS::SNPrint(name, sizeof(name), ":lt%s_%" Pd "", token_pos().ToCString(),
112 token_pos().ToCString(), vars_.length()); 105 vars_.length());
113 LocalVariable* temp_var = 106 LocalVariable* temp_var =
114 new LocalVariable(TokenPosition::kNoSource, 107 new LocalVariable(TokenPosition::kNoSource, token_pos(),
115 token_pos(),
116 String::ZoneHandle(zone, Symbols::New(thread, name)), 108 String::ZoneHandle(zone, Symbols::New(thread, name)),
117 Object::dynamic_type()); 109 Object::dynamic_type());
118 vars_.Add(temp_var); 110 vars_.Add(temp_var);
119 return temp_var; 111 return temp_var;
120 } 112 }
121 113
122 114
123 void LetNode::VisitChildren(AstNodeVisitor* visitor) const { 115 void LetNode::VisitChildren(AstNodeVisitor* visitor) const {
124 for (intptr_t i = 0; i < num_temps(); ++i) { 116 for (intptr_t i = 0; i < num_temps(); ++i) {
125 initializers_[i]->Visit(visitor); 117 initializers_[i]->Visit(visitor);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 return NULL; 218 return NULL;
227 } 219 }
228 220
229 221
230 const char* TypeNode::TypeName() const { 222 const char* TypeNode::TypeName() const {
231 return String::Handle(type().UserVisibleName()).ToCString(); 223 return String::Handle(type().UserVisibleName()).ToCString();
232 } 224 }
233 225
234 226
235 bool ComparisonNode::IsKindValid() const { 227 bool ComparisonNode::IsKindValid() const {
236 return Token::IsRelationalOperator(kind_) 228 return Token::IsRelationalOperator(kind_) ||
237 || Token::IsEqualityOperator(kind_) 229 Token::IsEqualityOperator(kind_) || Token::IsTypeTestOperator(kind_) ||
238 || Token::IsTypeTestOperator(kind_) 230 Token::IsTypeCastOperator(kind_);
239 || Token::IsTypeCastOperator(kind_);
240 } 231 }
241 232
242 233
243 const char* ComparisonNode::TokenName() const { 234 const char* ComparisonNode::TokenName() const {
244 return (kind_ == Token::kAS) ? "as" : Token::Str(kind_); 235 return (kind_ == Token::kAS) ? "as" : Token::Str(kind_);
245 } 236 }
246 237
247 238
248 bool ComparisonNode::IsPotentiallyConst() const { 239 bool ComparisonNode::IsPotentiallyConst() const {
249 switch (kind_) { 240 switch (kind_) {
250 case Token::kLT: 241 case Token::kLT:
251 case Token::kGT: 242 case Token::kGT:
252 case Token::kLTE: 243 case Token::kLTE:
253 case Token::kGTE: 244 case Token::kGTE:
254 case Token::kEQ: 245 case Token::kEQ:
255 case Token::kNE: 246 case Token::kNE:
256 case Token::kEQ_STRICT: 247 case Token::kEQ_STRICT:
257 case Token::kNE_STRICT: 248 case Token::kNE_STRICT:
258 return this->left()->IsPotentiallyConst() && 249 return this->left()->IsPotentiallyConst() &&
259 this->right()->IsPotentiallyConst(); 250 this->right()->IsPotentiallyConst();
260 default: 251 default:
261 return false; 252 return false;
262 } 253 }
263 } 254 }
264 255
265 256
266 const Instance* ComparisonNode::EvalConstExpr() const { 257 const Instance* ComparisonNode::EvalConstExpr() const {
267 const Instance* left_val = this->left()->EvalConstExpr(); 258 const Instance* left_val = this->left()->EvalConstExpr();
268 if (left_val == NULL) { 259 if (left_val == NULL) {
269 return NULL; 260 return NULL;
270 } 261 }
271 const Instance* right_val = this->right()->EvalConstExpr(); 262 const Instance* right_val = this->right()->EvalConstExpr();
272 if (right_val == NULL) { 263 if (right_val == NULL) {
273 return NULL; 264 return NULL;
274 } 265 }
275 switch (kind_) { 266 switch (kind_) {
276 case Token::kLT: 267 case Token::kLT:
277 case Token::kGT: 268 case Token::kGT:
278 case Token::kLTE: 269 case Token::kLTE:
279 case Token::kGTE: 270 case Token::kGTE:
280 if ((left_val->IsNumber() || left_val->IsNull()) && 271 if ((left_val->IsNumber() || left_val->IsNull()) &&
281 (right_val->IsNumber() || right_val->IsNull())) { 272 (right_val->IsNumber() || right_val->IsNull())) {
282 return &Bool::False(); 273 return &Bool::False();
283 } 274 }
284 return NULL; 275 return NULL;
285 case Token::kEQ: 276 case Token::kEQ:
286 case Token::kNE: 277 case Token::kNE:
287 // The comparison is a compile time const if both operands are either a 278 // The comparison is a compile time const if both operands are either a
288 // number, string, or boolean value (but not necessarily the same type). 279 // number, string, or boolean value (but not necessarily the same type).
289 if ((left_val->IsNumber() || 280 if ((left_val->IsNumber() || left_val->IsString() || left_val->IsBool() ||
290 left_val->IsString() || 281 left_val->IsNull()) &&
291 left_val->IsBool() || 282 (right_val->IsNumber() || right_val->IsString() ||
292 left_val->IsNull()) && 283 right_val->IsBool() || right_val->IsNull())) {
293 (right_val->IsNumber() ||
294 right_val->IsString() ||
295 right_val->IsBool() ||
296 right_val->IsNull())) {
297 return &Bool::False(); 284 return &Bool::False();
298 } 285 }
299 return NULL; 286 return NULL;
300 case Token::kEQ_STRICT: 287 case Token::kEQ_STRICT:
301 case Token::kNE_STRICT: 288 case Token::kNE_STRICT:
302 // identical(a, b) is a compile time const if both operands are 289 // identical(a, b) is a compile time const if both operands are
303 // compile time constants, regardless of their type. 290 // compile time constants, regardless of their type.
304 return &Bool::True(); 291 return &Bool::True();
305 default: 292 default:
306 return NULL; 293 return NULL;
307 } 294 }
308 return NULL; 295 return NULL;
309 } 296 }
310 297
311 298
312
313 bool BinaryOpNode::IsKindValid() const { 299 bool BinaryOpNode::IsKindValid() const {
314 switch (kind_) { 300 switch (kind_) {
315 case Token::kADD: 301 case Token::kADD:
316 case Token::kSUB: 302 case Token::kSUB:
317 case Token::kMUL: 303 case Token::kMUL:
318 case Token::kDIV: 304 case Token::kDIV:
319 case Token::kTRUNCDIV: 305 case Token::kTRUNCDIV:
320 case Token::kMOD: 306 case Token::kMOD:
321 case Token::kOR: 307 case Token::kOR:
322 case Token::kAND: 308 case Token::kAND:
(...skipping 20 matching lines...) Expand all
343 case Token::kOR: 329 case Token::kOR:
344 case Token::kAND: 330 case Token::kAND:
345 if (this->left()->IsLiteralNode() && 331 if (this->left()->IsLiteralNode() &&
346 this->left()->AsLiteralNode()->literal().IsNull()) { 332 this->left()->AsLiteralNode()->literal().IsNull()) {
347 return false; 333 return false;
348 } 334 }
349 if (this->right()->IsLiteralNode() && 335 if (this->right()->IsLiteralNode() &&
350 this->right()->AsLiteralNode()->literal().IsNull()) { 336 this->right()->AsLiteralNode()->literal().IsNull()) {
351 return false; 337 return false;
352 } 338 }
353 // Fall-through intentional. 339 // Fall-through intentional.
354 case Token::kADD: 340 case Token::kADD:
355 case Token::kSUB: 341 case Token::kSUB:
356 case Token::kMUL: 342 case Token::kMUL:
357 case Token::kDIV: 343 case Token::kDIV:
358 case Token::kMOD: 344 case Token::kMOD:
359 case Token::kTRUNCDIV: 345 case Token::kTRUNCDIV:
360 case Token::kBIT_OR: 346 case Token::kBIT_OR:
361 case Token::kBIT_XOR: 347 case Token::kBIT_XOR:
362 case Token::kBIT_AND: 348 case Token::kBIT_AND:
363 case Token::kSHL: 349 case Token::kSHL:
364 case Token::kSHR: 350 case Token::kSHR:
365 case Token::kIFNULL: 351 case Token::kIFNULL:
366 return this->left()->IsPotentiallyConst() && 352 return this->left()->IsPotentiallyConst() &&
367 this->right()->IsPotentiallyConst(); 353 this->right()->IsPotentiallyConst();
368 default: 354 default:
369 UNREACHABLE(); 355 UNREACHABLE();
370 return false; 356 return false;
371 } 357 }
372 } 358 }
373 359
374 360
375 const Instance* BinaryOpNode::EvalConstExpr() const { 361 const Instance* BinaryOpNode::EvalConstExpr() const {
376 const Instance* left_val = this->left()->EvalConstExpr(); 362 const Instance* left_val = this->left()->EvalConstExpr();
377 if (left_val == NULL) { 363 if (left_val == NULL) {
378 return NULL; 364 return NULL;
379 } 365 }
380 if (!left_val->IsNumber() && !left_val->IsBool() && !left_val->IsString() && 366 if (!left_val->IsNumber() && !left_val->IsBool() && !left_val->IsString() &&
381 kind_ != Token::kIFNULL) { 367 kind_ != Token::kIFNULL) {
382 return NULL; 368 return NULL;
383 } 369 }
384 const Instance* right_val = this->right()->EvalConstExpr(); 370 const Instance* right_val = this->right()->EvalConstExpr();
385 if (right_val == NULL) { 371 if (right_val == NULL) {
386 return NULL; 372 return NULL;
387 } 373 }
388 switch (kind_) { 374 switch (kind_) {
389 case Token::kADD: 375 case Token::kADD:
390 if (left_val->IsString()) { 376 if (left_val->IsString()) {
391 return right_val->IsString() ? left_val : NULL; 377 return right_val->IsString() ? left_val : NULL;
392 } 378 }
393 // Fall-through intentional. 379 // Fall-through intentional.
394 case Token::kSUB: 380 case Token::kSUB:
395 case Token::kMUL: 381 case Token::kMUL:
396 case Token::kDIV: 382 case Token::kDIV:
397 case Token::kMOD: 383 case Token::kMOD:
398 case Token::kTRUNCDIV: 384 case Token::kTRUNCDIV:
399 if (left_val->IsInteger()) { 385 if (left_val->IsInteger()) {
400 if (right_val->IsInteger()) { 386 if (right_val->IsInteger()) {
401 return left_val; 387 return left_val;
402 } else if (right_val->IsNumber()) { 388 } else if (right_val->IsNumber()) {
403 return right_val; 389 return right_val;
404 } 390 }
405 } else if (left_val->IsNumber() && 391 } else if (left_val->IsNumber() && right_val->IsNumber()) {
406 right_val->IsNumber()) {
407 return left_val; 392 return left_val;
408 } 393 }
409 return NULL; 394 return NULL;
410 case Token::kBIT_OR: 395 case Token::kBIT_OR:
411 case Token::kBIT_XOR: 396 case Token::kBIT_XOR:
412 case Token::kBIT_AND: 397 case Token::kBIT_AND:
413 case Token::kSHL: 398 case Token::kSHL:
414 case Token::kSHR: 399 case Token::kSHR:
415 if (left_val->IsInteger() && 400 if (left_val->IsInteger() && right_val->IsInteger()) {
416 right_val->IsInteger()) {
417 return right_val; 401 return right_val;
418 } 402 }
419 return NULL; 403 return NULL;
420 case Token::kOR: 404 case Token::kOR:
421 case Token::kAND: 405 case Token::kAND:
422 if (left_val->IsBool() && right_val->IsBool()) { 406 if (left_val->IsBool() && right_val->IsBool()) {
423 return left_val; 407 return left_val;
424 } 408 }
425 return NULL; 409 return NULL;
426 case Token::kIFNULL: 410 case Token::kIFNULL:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 case Token::kBIT_NOT: 465 case Token::kBIT_NOT:
482 return val->IsInteger() ? val : NULL; 466 return val->IsInteger() ? val : NULL;
483 default: 467 default:
484 return NULL; 468 return NULL;
485 } 469 }
486 } 470 }
487 471
488 472
489 bool ConditionalExprNode::IsPotentiallyConst() const { 473 bool ConditionalExprNode::IsPotentiallyConst() const {
490 return this->condition()->IsPotentiallyConst() && 474 return this->condition()->IsPotentiallyConst() &&
491 this->true_expr()->IsPotentiallyConst() && 475 this->true_expr()->IsPotentiallyConst() &&
492 this->false_expr()->IsPotentiallyConst(); 476 this->false_expr()->IsPotentiallyConst();
493 } 477 }
494 478
495 479
496 const Instance* ConditionalExprNode::EvalConstExpr() const { 480 const Instance* ConditionalExprNode::EvalConstExpr() const {
497 const Instance* cond = this->condition()->EvalConstExpr(); 481 const Instance* cond = this->condition()->EvalConstExpr();
498 if ((cond != NULL) && 482 if ((cond != NULL) && cond->IsBool() &&
499 cond->IsBool() &&
500 (this->true_expr()->EvalConstExpr() != NULL) && 483 (this->true_expr()->EvalConstExpr() != NULL) &&
501 (this->false_expr()->EvalConstExpr() != NULL)) { 484 (this->false_expr()->EvalConstExpr() != NULL)) {
502 return cond; 485 return cond;
503 } 486 }
504 return NULL; 487 return NULL;
505 } 488 }
506 489
507 490
508 bool ClosureNode::IsPotentiallyConst() const { 491 bool ClosureNode::IsPotentiallyConst() const {
509 if (function().IsImplicitStaticClosureFunction()) { 492 if (function().IsImplicitStaticClosureFunction()) {
510 return true; 493 return true;
511 } 494 }
512 return false; 495 return false;
513 } 496 }
514 497
515 498
516 const Instance* ClosureNode::EvalConstExpr() const { 499 const Instance* ClosureNode::EvalConstExpr() const {
517 if (!is_deferred_reference_ && 500 if (!is_deferred_reference_ && function().IsImplicitStaticClosureFunction()) {
518 function().IsImplicitStaticClosureFunction()) {
519 // Return a value that represents an instance. Only the type is relevant. 501 // Return a value that represents an instance. Only the type is relevant.
520 return &Instance::Handle(); 502 return &Instance::Handle();
521 } 503 }
522 return NULL; 504 return NULL;
523 } 505 }
524 506
525 507
526 AstNode* ClosureNode::MakeAssignmentNode(AstNode* rhs) { 508 AstNode* ClosureNode::MakeAssignmentNode(AstNode* rhs) {
527 if (scope() == NULL) { 509 if (scope() == NULL) {
528 // This is an implicit closure node created because a static getter was not 510 // This is an implicit closure node created because a static getter was not
529 // found. Change the getter into a setter. If it does not exist, 511 // found. Change the getter into a setter. If it does not exist,
530 // noSuchMethod will be called. 512 // noSuchMethod will be called.
531 return new StaticSetterNode(token_pos(), 513 return new StaticSetterNode(token_pos(), receiver(),
532 receiver(),
533 Class::ZoneHandle(function().Owner()), 514 Class::ZoneHandle(function().Owner()),
534 String::ZoneHandle(function().name()), 515 String::ZoneHandle(function().name()), rhs);
535 rhs);
536 } 516 }
537 return NULL; 517 return NULL;
538 } 518 }
539 519
540 520
541 const char* UnaryOpNode::TokenName() const { 521 const char* UnaryOpNode::TokenName() const {
542 return Token::Str(kind_); 522 return Token::Str(kind_);
543 } 523 }
544 524
545 525
(...skipping 26 matching lines...) Expand all
572 } 552 }
573 return new StoreLocalNode(token_pos(), &local(), rhs); 553 return new StoreLocalNode(token_pos(), &local(), rhs);
574 } 554 }
575 555
576 556
577 AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) { 557 AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) {
578 if (field().is_final()) { 558 if (field().is_final()) {
579 return NULL; 559 return NULL;
580 } 560 }
581 if (Isolate::Current()->type_checks()) { 561 if (Isolate::Current()->type_checks()) {
582 rhs = new AssignableNode( 562 rhs = new AssignableNode(field().token_pos(), rhs,
583 field().token_pos(), 563 AbstractType::ZoneHandle(field().type()),
584 rhs, 564 String::ZoneHandle(field().name()));
585 AbstractType::ZoneHandle(field().type()),
586 String::ZoneHandle(field().name()));
587 } 565 }
588 return new StoreStaticFieldNode( 566 return new StoreStaticFieldNode(token_pos(),
589 token_pos(), Field::ZoneHandle(field().Original()), rhs); 567 Field::ZoneHandle(field().Original()), rhs);
590 } 568 }
591 569
592 570
593 AstNode* InstanceGetterNode::MakeAssignmentNode(AstNode* rhs) { 571 AstNode* InstanceGetterNode::MakeAssignmentNode(AstNode* rhs) {
594 return new InstanceSetterNode(token_pos(), 572 return new InstanceSetterNode(token_pos(), receiver(), field_name(), rhs,
595 receiver(),
596 field_name(),
597 rhs,
598 is_conditional()); 573 is_conditional());
599 } 574 }
600 575
601 576
602 bool InstanceGetterNode::IsPotentiallyConst() const { 577 bool InstanceGetterNode::IsPotentiallyConst() const {
603 return field_name().Equals(Symbols::Length()) && 578 return field_name().Equals(Symbols::Length()) && !is_conditional() &&
604 !is_conditional() && 579 receiver()->IsPotentiallyConst();
605 receiver()->IsPotentiallyConst();
606 } 580 }
607 581
608 582
609 const Instance* InstanceGetterNode::EvalConstExpr() const { 583 const Instance* InstanceGetterNode::EvalConstExpr() const {
610 if (field_name().Equals(Symbols::Length()) && !is_conditional()) { 584 if (field_name().Equals(Symbols::Length()) && !is_conditional()) {
611 const Instance* receiver_val = receiver()->EvalConstExpr(); 585 const Instance* receiver_val = receiver()->EvalConstExpr();
612 if ((receiver_val != NULL) && receiver_val->IsString()) { 586 if ((receiver_val != NULL) && receiver_val->IsString()) {
613 return &Instance::ZoneHandle(Smi::New(1)); 587 return &Instance::ZoneHandle(Smi::New(1));
614 } 588 }
615 } 589 }
616 return NULL; 590 return NULL;
617 } 591 }
618 592
619 593
620 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { 594 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) {
621 return new StoreIndexedNode(token_pos(), array(), index_expr(), 595 return new StoreIndexedNode(token_pos(), array(), index_expr(), rhs,
622 rhs, super_class()); 596 super_class());
623 } 597 }
624 598
625 599
626 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { 600 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
627 Thread* thread = Thread::Current(); 601 Thread* thread = Thread::Current();
628 Zone* zone = thread->zone(); 602 Zone* zone = thread->zone();
629 Isolate* isolate = thread->isolate(); 603 Isolate* isolate = thread->isolate();
630 if (is_super_getter()) { 604 if (is_super_getter()) {
631 ASSERT(receiver() != NULL); 605 ASSERT(receiver() != NULL);
632 const String& setter_name = 606 const String& setter_name =
633 String::ZoneHandle(zone, Field::LookupSetterSymbol(field_name_)); 607 String::ZoneHandle(zone, Field::LookupSetterSymbol(field_name_));
634 Function& setter = Function::ZoneHandle(zone); 608 Function& setter = Function::ZoneHandle(zone);
635 if (!setter_name.IsNull()) { 609 if (!setter_name.IsNull()) {
636 setter = Resolver::ResolveDynamicAnyArgs(zone, cls(), setter_name); 610 setter = Resolver::ResolveDynamicAnyArgs(zone, cls(), setter_name);
637 } 611 }
638 if (setter.IsNull() || setter.is_abstract()) { 612 if (setter.IsNull() || setter.is_abstract()) {
639 // No instance setter found in super class chain, 613 // No instance setter found in super class chain,
640 // noSuchMethod will be called at runtime. 614 // noSuchMethod will be called at runtime.
641 return new StaticSetterNode(token_pos(), 615 return new StaticSetterNode(token_pos(), receiver(), cls(), field_name_,
642 receiver(),
643 cls(),
644 field_name_,
645 rhs); 616 rhs);
646 } 617 }
647 return new StaticSetterNode(token_pos(), 618 return new StaticSetterNode(token_pos(), receiver(), field_name_, setter,
648 receiver(),
649 field_name_,
650 setter,
651 rhs); 619 rhs);
652 } 620 }
653 621
654 if (owner().IsLibraryPrefix()) { 622 if (owner().IsLibraryPrefix()) {
655 const LibraryPrefix& prefix = LibraryPrefix::Cast(owner_); 623 const LibraryPrefix& prefix = LibraryPrefix::Cast(owner_);
656 // The parser has already dealt with the pathological case where a 624 // The parser has already dealt with the pathological case where a
657 // library imports itself. See Parser::ResolveIdentInPrefixScope() 625 // library imports itself. See Parser::ResolveIdentInPrefixScope()
658 ASSERT(field_name_.CharAt(0) != Library::kPrivateIdentifierStart); 626 ASSERT(field_name_.CharAt(0) != Library::kPrivateIdentifierStart);
659 627
660 // If the prefix is not yet loaded, the getter doesn't exist. Return a 628 // If the prefix is not yet loaded, the getter doesn't exist. Return a
661 // setter that will throw a NSME at runtime. 629 // setter that will throw a NSME at runtime.
662 if (!prefix.is_loaded()) { 630 if (!prefix.is_loaded()) {
663 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 631 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
664 } 632 }
665 633
666 Object& obj = Object::Handle(zone, prefix.LookupObject(field_name_)); 634 Object& obj = Object::Handle(zone, prefix.LookupObject(field_name_));
667 if (obj.IsField()) { 635 if (obj.IsField()) {
668 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw()); 636 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw());
669 if (!field.is_final()) { 637 if (!field.is_final()) {
670 if (isolate->type_checks()) { 638 if (isolate->type_checks()) {
671 rhs = new AssignableNode(field.token_pos(), 639 rhs = new AssignableNode(field.token_pos(), rhs,
672 rhs,
673 AbstractType::ZoneHandle(zone, field.type()), 640 AbstractType::ZoneHandle(zone, field.type()),
674 field_name_); 641 field_name_);
675 } 642 }
676 return new StoreStaticFieldNode(token_pos(), field, rhs); 643 return new StoreStaticFieldNode(token_pos(), field, rhs);
677 } 644 }
678 } 645 }
679 646
680 // No field found in prefix. Look for a setter function. 647 // No field found in prefix. Look for a setter function.
681 const String& setter_name = 648 const String& setter_name =
682 String::Handle(zone, Field::LookupSetterSymbol(field_name_)); 649 String::Handle(zone, Field::LookupSetterSymbol(field_name_));
683 if (!setter_name.IsNull()) { 650 if (!setter_name.IsNull()) {
684 obj = prefix.LookupObject(setter_name); 651 obj = prefix.LookupObject(setter_name);
685 if (obj.IsFunction()) { 652 if (obj.IsFunction()) {
686 const Function& setter = 653 const Function& setter =
687 Function::ZoneHandle(zone, Function::Cast(obj).raw()); 654 Function::ZoneHandle(zone, Function::Cast(obj).raw());
688 ASSERT(setter.is_static() && setter.IsSetterFunction()); 655 ASSERT(setter.is_static() && setter.IsSetterFunction());
689 return new StaticSetterNode( 656 return new StaticSetterNode(token_pos(), NULL, field_name_, setter,
690 token_pos(), NULL, field_name_, setter, rhs); 657 rhs);
691 } 658 }
692 } 659 }
693 660
694 // No writeable field and no setter found in the prefix. Return a 661 // No writeable field and no setter found in the prefix. Return a
695 // non-existing setter that will throw an NSM error. 662 // non-existing setter that will throw an NSM error.
696 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 663 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
697 } 664 }
698 665
699 if (owner().IsLibrary()) { 666 if (owner().IsLibrary()) {
700 const Library& library = Library::Cast(owner()); 667 const Library& library = Library::Cast(owner());
701 Object& obj = Object::Handle(zone, library.ResolveName(field_name_)); 668 Object& obj = Object::Handle(zone, library.ResolveName(field_name_));
702 if (obj.IsField()) { 669 if (obj.IsField()) {
703 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw()); 670 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw());
704 if (!field.is_final()) { 671 if (!field.is_final()) {
705 if (isolate->type_checks()) { 672 if (isolate->type_checks()) {
706 rhs = new AssignableNode(field.token_pos(), 673 rhs = new AssignableNode(field.token_pos(), rhs,
707 rhs,
708 AbstractType::ZoneHandle(zone, field.type()), 674 AbstractType::ZoneHandle(zone, field.type()),
709 field_name_); 675 field_name_);
710 } 676 }
711 return new StoreStaticFieldNode(token_pos(), field, rhs); 677 return new StoreStaticFieldNode(token_pos(), field, rhs);
712 } 678 }
713 } 679 }
714 680
715 // No field found in library. Look for a setter function. 681 // No field found in library. Look for a setter function.
716 const String& setter_name = 682 const String& setter_name =
717 String::Handle(zone, Field::LookupSetterSymbol(field_name_)); 683 String::Handle(zone, Field::LookupSetterSymbol(field_name_));
718 if (!setter_name.IsNull()) { 684 if (!setter_name.IsNull()) {
719 obj = library.ResolveName(setter_name); 685 obj = library.ResolveName(setter_name);
720 if (obj.IsFunction()) { 686 if (obj.IsFunction()) {
721 const Function& setter = 687 const Function& setter =
722 Function::ZoneHandle(zone, Function::Cast(obj).raw()); 688 Function::ZoneHandle(zone, Function::Cast(obj).raw());
723 ASSERT(setter.is_static() && setter.IsSetterFunction()); 689 ASSERT(setter.is_static() && setter.IsSetterFunction());
724 return 690 return new StaticSetterNode(token_pos(), NULL, field_name_, setter,
725 new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); 691 rhs);
726 } 692 }
727 } 693 }
728 694
729 // No writeable field and no setter found in the library. Return a 695 // No writeable field and no setter found in the library. Return a
730 // non-existing setter that will throw an NSM error. 696 // non-existing setter that will throw an NSM error.
731 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 697 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
732 } 698 }
733 699
734 const Function& setter = 700 const Function& setter =
735 Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_)); 701 Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_));
736 if (!setter.IsNull() && setter.IsStaticFunction()) { 702 if (!setter.IsNull() && setter.IsStaticFunction()) {
737 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); 703 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs);
738 } 704 }
739 // Could not find a static setter. Look for a field. 705 // Could not find a static setter. Look for a field.
740 // Access to a lazily initialized static field that has not yet been 706 // Access to a lazily initialized static field that has not yet been
741 // initialized is compiled to a static implicit getter. 707 // initialized is compiled to a static implicit getter.
742 // A setter may not exist for such a field. 708 // A setter may not exist for such a field.
743 const Field& field = Field::ZoneHandle(zone, 709 const Field& field =
744 cls().LookupStaticField(field_name_)); 710 Field::ZoneHandle(zone, cls().LookupStaticField(field_name_));
745 if (!field.IsNull()) { 711 if (!field.IsNull()) {
746 if (field.is_final()) { 712 if (field.is_final()) {
747 // Attempting to assign to a final variable will cause a NoSuchMethodError 713 // Attempting to assign to a final variable will cause a NoSuchMethodError
748 // to be thrown. Change static getter to non-existent static setter in 714 // to be thrown. Change static getter to non-existent static setter in
749 // order to trigger the throw at runtime. 715 // order to trigger the throw at runtime.
750 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 716 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
751 } 717 }
752 #if defined(DEBUG) 718 #if defined(DEBUG)
753 const String& getter_name = 719 const String& getter_name =
754 String::Handle(zone, Field::LookupGetterSymbol(field_name_)); 720 String::Handle(zone, Field::LookupGetterSymbol(field_name_));
755 ASSERT(!getter_name.IsNull()); 721 ASSERT(!getter_name.IsNull());
756 const Function& getter = 722 const Function& getter =
757 Function::Handle(zone, cls().LookupStaticFunction(getter_name)); 723 Function::Handle(zone, cls().LookupStaticFunction(getter_name));
758 ASSERT(!getter.IsNull() && 724 ASSERT(!getter.IsNull() &&
759 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); 725 (getter.kind() == RawFunction::kImplicitStaticFinalGetter));
760 #endif 726 #endif
761 if (isolate->type_checks()) { 727 if (isolate->type_checks()) {
762 rhs = new AssignableNode( 728 rhs = new AssignableNode(field.token_pos(), rhs,
763 field.token_pos(), 729 AbstractType::ZoneHandle(zone, field.type()),
764 rhs, 730 String::ZoneHandle(zone, field.name()));
765 AbstractType::ZoneHandle(zone, field.type()),
766 String::ZoneHandle(zone, field.name()));
767 } 731 }
768 return new StoreStaticFieldNode(token_pos(), field, rhs); 732 return new StoreStaticFieldNode(token_pos(), field, rhs);
769 } 733 }
770 // Didn't find a static setter or a static field. Make a call to 734 // Didn't find a static setter or a static field. Make a call to
771 // the non-existent setter to trigger a NoSuchMethodError at runtime. 735 // the non-existent setter to trigger a NoSuchMethodError at runtime.
772 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 736 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
773 } 737 }
774 738
775 739
776 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { 740 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 if (result.IsError() || result.IsNull()) { 785 if (result.IsError() || result.IsNull()) {
822 // TODO(turnidge): We could get better error messages by returning 786 // TODO(turnidge): We could get better error messages by returning
823 // the Error object directly to the parser. This will involve 787 // the Error object directly to the parser. This will involve
824 // replumbing all of the EvalConstExpr methods. 788 // replumbing all of the EvalConstExpr methods.
825 return NULL; 789 return NULL;
826 } 790 }
827 return &Instance::ZoneHandle(Instance::Cast(result).raw()); 791 return &Instance::ZoneHandle(Instance::Cast(result).raw());
828 } 792 }
829 793
830 } // namespace dart 794 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/ast.h ('k') | runtime/vm/ast_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698