| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 6024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6035 if (label != NULL) { | 6035 if (label != NULL) { |
| 6036 current_block_->statements->Add(if_node); | 6036 current_block_->statements->Add(if_node); |
| 6037 SequenceNode* sequence = CloseBlock(); | 6037 SequenceNode* sequence = CloseBlock(); |
| 6038 sequence->set_label(label); | 6038 sequence->set_label(label); |
| 6039 if_node = sequence; | 6039 if_node = sequence; |
| 6040 } | 6040 } |
| 6041 return if_node; | 6041 return if_node; |
| 6042 } | 6042 } |
| 6043 | 6043 |
| 6044 | 6044 |
| 6045 // Return true if the type class of the given value implements the |
| 6046 // == operator. |
| 6047 static bool ImplementsEqualOperator(const Instance& value) { |
| 6048 Class& cls = Class::Handle(value.clazz()); |
| 6049 const Function& equal_op = Function::Handle( |
| 6050 Resolver::ResolveDynamicAnyArgs(cls, Symbols::EqualOperator())); |
| 6051 ASSERT(!equal_op.IsNull()); |
| 6052 cls = equal_op.Owner(); |
| 6053 return !cls.IsObjectClass(); |
| 6054 } |
| 6055 |
| 6056 |
| 6045 // Check that all case expressions are of the same type, either int, String, | 6057 // Check that all case expressions are of the same type, either int, String, |
| 6046 // double or any other class that does not override the == operator. | 6058 // or any other class that does not override the == operator. |
| 6047 // The expressions are compile-time constants and are thus in the form | 6059 // The expressions are compile-time constants and are thus in the form |
| 6048 // of a LiteralNode. | 6060 // of a LiteralNode. |
| 6049 void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) { | 6061 void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) { |
| 6050 const intptr_t num_expressions = values.length(); | 6062 const intptr_t num_expressions = values.length(); |
| 6051 if (num_expressions == 0) { | 6063 if (num_expressions == 0) { |
| 6052 return; | 6064 return; |
| 6053 } | 6065 } |
| 6054 const Instance& first_value = values[0]->literal(); | 6066 const Instance& first_value = values[0]->literal(); |
| 6055 for (intptr_t i = 0; i < num_expressions; i++) { | 6067 for (intptr_t i = 0; i < num_expressions; i++) { |
| 6056 const Instance& val = values[i]->literal(); | 6068 const Instance& val = values[i]->literal(); |
| 6057 const intptr_t val_pos = values[i]->token_pos(); | 6069 const intptr_t val_pos = values[i]->token_pos(); |
| 6058 if (first_value.IsInteger()) { | 6070 if (first_value.IsInteger()) { |
| 6059 if (!val.IsInteger()) { | 6071 if (!val.IsInteger()) { |
| 6060 ErrorMsg(val_pos, "expected case expression of type int"); | 6072 ErrorMsg(val_pos, "expected case expression of type int"); |
| 6061 } | 6073 } |
| 6062 continue; | 6074 continue; |
| 6063 } | 6075 } |
| 6064 if (first_value.IsString()) { | 6076 if (first_value.IsString()) { |
| 6065 if (!val.IsString()) { | 6077 if (!val.IsString()) { |
| 6066 ErrorMsg(val_pos, "expected case expression of type String"); | 6078 ErrorMsg(val_pos, "expected case expression of type String"); |
| 6067 } | 6079 } |
| 6068 continue; | 6080 continue; |
| 6069 } | 6081 } |
| 6070 if (first_value.IsDouble()) { | 6082 if (val.IsDouble()) { |
| 6071 if (!val.IsDouble()) { | 6083 ErrorMsg(val_pos, "case expression may not be of type double"); |
| 6072 ErrorMsg(val_pos, "expected case expression of type double"); | |
| 6073 } | |
| 6074 continue; | |
| 6075 } | 6084 } |
| 6076 if (val.clazz() != first_value.clazz()) { | 6085 if (val.clazz() != first_value.clazz()) { |
| 6077 ErrorMsg(val_pos, "all case expressions must be of same type"); | 6086 ErrorMsg(val_pos, "all case expressions must be of same type"); |
| 6078 } | 6087 } |
| 6079 if (i == 0) { | 6088 if (i == 0) { |
| 6080 // The value is of some type other than int, String or double. | 6089 // The value is of some type other than int, String or double. |
| 6081 // Check that the type class does not override the == operator. | 6090 // Check that the type class does not override the == operator. |
| 6082 // Check this only in the first loop iteration since all values | 6091 // Check this only in the first loop iteration since all values |
| 6083 // are of the same type, which we check above. | 6092 // are of the same type, which we check above. |
| 6084 Class& cls = Class::Handle(val.clazz()); | 6093 if (ImplementsEqualOperator(val)) { |
| 6085 const Function& equal_op = Function::Handle( | |
| 6086 Resolver::ResolveDynamicAnyArgs(cls, Symbols::EqualOperator())); | |
| 6087 ASSERT(!equal_op.IsNull()); | |
| 6088 cls = equal_op.Owner(); | |
| 6089 if (!cls.IsObjectClass()) { | |
| 6090 ErrorMsg(val_pos, | 6094 ErrorMsg(val_pos, |
| 6091 "type class of case expression must not implement operator =="); | 6095 "type class of case expression must not implement operator =="); |
| 6092 } | 6096 } |
| 6093 } | 6097 } |
| 6094 } | 6098 } |
| 6095 } | 6099 } |
| 6096 | 6100 |
| 6097 | 6101 |
| 6098 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 6102 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 6099 GrowableArray<LiteralNode*>* case_expr_values, | 6103 GrowableArray<LiteralNode*>* case_expr_values, |
| (...skipping 3396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9496 const intptr_t key_pos = TokenPos(); | 9500 const intptr_t key_pos = TokenPos(); |
| 9497 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 9501 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
| 9498 if (FLAG_enable_type_checks && | 9502 if (FLAG_enable_type_checks && |
| 9499 !is_const && | 9503 !is_const && |
| 9500 !key_type.IsDynamicType()) { | 9504 !key_type.IsDynamicType()) { |
| 9501 key = new AssignableNode(key_pos, | 9505 key = new AssignableNode(key_pos, |
| 9502 key, | 9506 key, |
| 9503 key_type, | 9507 key_type, |
| 9504 Symbols::ListLiteralElement()); | 9508 Symbols::ListLiteralElement()); |
| 9505 } | 9509 } |
| 9510 if (is_const) { |
| 9511 ASSERT(key->IsLiteralNode()); |
| 9512 const Instance& key_value = key->AsLiteralNode()->literal(); |
| 9513 if (key_value.IsDouble()) { |
| 9514 ErrorMsg(key_pos, "key value must not be of type double"); |
| 9515 } |
| 9516 if (!key_value.IsInteger() && |
| 9517 !key_value.IsString() && |
| 9518 ImplementsEqualOperator(key_value)) { |
| 9519 ErrorMsg(key_pos, "key value must not implement operator =="); |
| 9520 } |
| 9521 } |
| 9506 ExpectToken(Token::kCOLON); | 9522 ExpectToken(Token::kCOLON); |
| 9507 const intptr_t value_pos = TokenPos(); | 9523 const intptr_t value_pos = TokenPos(); |
| 9508 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 9524 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
| 9509 SetAllowFunctionLiterals(saved_mode); | 9525 SetAllowFunctionLiterals(saved_mode); |
| 9510 if (FLAG_enable_type_checks && | 9526 if (FLAG_enable_type_checks && |
| 9511 !is_const && | 9527 !is_const && |
| 9512 !value_type.IsDynamicType()) { | 9528 !value_type.IsDynamicType()) { |
| 9513 value = new AssignableNode(value_pos, | 9529 value = new AssignableNode(value_pos, |
| 9514 value, | 9530 value, |
| 9515 value_type, | 9531 value_type, |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10604 void Parser::SkipQualIdent() { | 10620 void Parser::SkipQualIdent() { |
| 10605 ASSERT(IsIdentifier()); | 10621 ASSERT(IsIdentifier()); |
| 10606 ConsumeToken(); | 10622 ConsumeToken(); |
| 10607 if (CurrentToken() == Token::kPERIOD) { | 10623 if (CurrentToken() == Token::kPERIOD) { |
| 10608 ConsumeToken(); // Consume the kPERIOD token. | 10624 ConsumeToken(); // Consume the kPERIOD token. |
| 10609 ExpectIdentifier("identifier expected after '.'"); | 10625 ExpectIdentifier("identifier expected after '.'"); |
| 10610 } | 10626 } |
| 10611 } | 10627 } |
| 10612 | 10628 |
| 10613 } // namespace dart | 10629 } // namespace dart |
| OLD | NEW |