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

Unified Diff: runtime/vm/parser.cc

Issue 34413007: Implement type checks for switch expression (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-co19.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 29086)
+++ runtime/vm/parser.cc (working copy)
@@ -6024,10 +6024,11 @@
// or any other class that does not override the == operator.
// The expressions are compile-time constants and are thus in the form
// of a LiteralNode.
-void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) {
+RawClass* Parser::CheckCaseExpressions(
+ const GrowableArray<LiteralNode*>& values) {
const intptr_t num_expressions = values.length();
if (num_expressions == 0) {
- return;
+ return Object::dynamic_class();
}
const Instance& first_value = values[0]->literal();
for (intptr_t i = 0; i < num_expressions; i++) {
@@ -6062,6 +6063,12 @@
}
}
}
+ if (first_value.IsInteger()) {
+ return Type::Handle(Type::IntType()).type_class();
+ } else if (first_value.IsString()) {
+ return Type::Handle(Type::StringType()).type_class();
+ }
+ return first_value.clazz();
}
@@ -6160,11 +6167,18 @@
OpenBlock();
current_block_->scope->AddLabel(label);
- // Store switch expression in temporary local variable.
+ // Store switch expression in temporary local variable. The type of the
+ // variable is set to dynamic. It will later be patched to match the
+ // type of the case clause expressions. Therefore, we have to allocate
+ // a new type representing dynamic and can't reuse the canonical
+ // type object for dynamic.
+ const Type& temp_var_type =
+ Type::ZoneHandle(Type::New(Class::Handle(Object::dynamic_class()),
+ TypeArguments::Handle(),
+ expr_pos));
+ temp_var_type.SetIsFinalized();
LocalVariable* temp_variable =
- new LocalVariable(expr_pos,
- Symbols::SwitchExpr(),
- Type::ZoneHandle(Type::DynamicType()));
+ new LocalVariable(expr_pos, Symbols::SwitchExpr(), temp_var_type);
current_block_->scope->AddVariable(temp_variable);
AstNode* save_switch_expr =
new StoreLocalNode(expr_pos, temp_variable, switch_expr);
@@ -6217,8 +6231,11 @@
}
// Check that all expressions in case clauses are of the same class,
- // or implement int, double or String.
- CheckCaseExpressions(case_expr_values);
+ // or implement int, double or String. Patch the type of the temporary
+ // variable holding the switch expression to match the type of the
+ // case clause constants.
+ temp_var_type.set_type_class(
+ Class::Handle(CheckCaseExpressions(case_expr_values)));
// Check for unresolved label references.
SourceLabel* unresolved_label =
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-co19.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698