| Index: runtime/vm/ast.cc
|
| ===================================================================
|
| --- runtime/vm/ast.cc (revision 43830)
|
| +++ runtime/vm/ast.cc (working copy)
|
| @@ -324,7 +324,7 @@
|
| if (left_val == NULL) {
|
| return NULL;
|
| }
|
| - if (!left_val->IsNumber() && !left_val->IsBool()) {
|
| + if (!left_val->IsNumber() && !left_val->IsBool() && !left_val->IsString()) {
|
| return NULL;
|
| }
|
| const Instance* right_val = this->right()->EvalConstExpr();
|
| @@ -333,6 +333,10 @@
|
| }
|
| switch (kind_) {
|
| case Token::kADD:
|
| + if (left_val->IsString()) {
|
| + return right_val->IsString() ? left_val : NULL;
|
| + }
|
| + // Fall-through intentional.
|
| case Token::kSUB:
|
| case Token::kMUL:
|
| case Token::kDIV:
|
| @@ -531,6 +535,23 @@
|
| }
|
|
|
|
|
| +bool InstanceGetterNode::IsPotentiallyConst() const {
|
| + return field_name().Equals(Symbols::Length()) &&
|
| + receiver()->IsPotentiallyConst();
|
| +}
|
| +
|
| +
|
| +const Instance* InstanceGetterNode::EvalConstExpr() const {
|
| + if (field_name().Equals(Symbols::Length())) {
|
| + const Instance* receiver_val = receiver()->EvalConstExpr();
|
| + if ((receiver_val != NULL) && receiver_val->IsString()) {
|
| + return &Instance::ZoneHandle(Smi::New(1));
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) {
|
| return new StoreIndexedNode(token_pos(), array(), index_expr(),
|
| rhs, super_class());
|
|
|