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

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

Issue 25561002: Disallow double in case clauses and const map literal keys (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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
« no previous file with comments | « no previous file | tests/co19/co19-dart2dart.status » ('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) 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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-dart2dart.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698