mirror of
https://github.com/dart-lang/sdk
synced 2024-09-23 00:23:57 +00:00
Implement type checks for switch expression
If the switch expression is not compatible with the case clause constants, we must report a runtime error. Implement this by annotating the temporary variable holding the switch expression with the correct type. Issue 7274 R=regis@google.com Review URL: https://codereview.chromium.org//34413007 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@29126 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
45e20b5921
commit
ddd9907e23
|
@ -6028,10 +6028,11 @@ static bool ImplementsEqualOperator(const Instance& value) {
|
|||
// 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++) {
|
||||
|
@ -6066,6 +6067,12 @@ void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) {
|
|||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -6164,11 +6171,18 @@ AstNode* Parser::ParseSwitchStatement(String* label_name) {
|
|||
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);
|
||||
|
@ -6221,8 +6235,11 @@ AstNode* Parser::ParseSwitchStatement(String* label_name) {
|
|||
}
|
||||
|
||||
// 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 =
|
||||
|
|
|
@ -498,7 +498,7 @@ class Parser : public ValueObject {
|
|||
AstNode* ParseDoWhileStatement(String* label_name);
|
||||
AstNode* ParseForStatement(String* label_name);
|
||||
AstNode* ParseForInStatement(intptr_t forin_pos, SourceLabel* label);
|
||||
void CheckCaseExpressions(const GrowableArray<LiteralNode*>& values);
|
||||
RawClass* CheckCaseExpressions(const GrowableArray<LiteralNode*>& values);
|
||||
CaseNode* ParseCaseClause(LocalVariable* switch_expr_value,
|
||||
GrowableArray<LiteralNode*>* case_expr_values,
|
||||
SourceLabel* case_label);
|
||||
|
|
|
@ -162,8 +162,8 @@ LibTest/async/StreamEventTransformer/handleError_A01_t01: Fail # co19 issue 626
|
|||
### CHECKED MODE FAILURES ###
|
||||
|
||||
[ ($runtime == vm || $compiler == dart2js) && $checked]
|
||||
Language/13_Statements/09_Switch_A09_t01: PASS, FAIL, OK # co19 issue 633
|
||||
Language/07_Classes/6_Constructors/2_Factories_A12_t02: fail # co19-roll r587: Please triage this failure
|
||||
Language/13_Statements/09_Switch_A05_t01: FAIL, OK # co19 issue 498
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t46: PASS, FAIL, OK # co19 issue 560
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t66: PASS, FAIL, OK # co19 issue 560
|
||||
LibTest/async/EventTransformStream/contains_A01_t01: FAIL, OK # co19 issue 498
|
||||
|
|
Loading…
Reference in a new issue