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

Unified Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 184663004: Follow factory redirections when checking case expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. (500) Created 6 years, 10 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 | « no previous file | sdk/lib/_internal/compiler/implementation/typechecker.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 1ea01a85e38bdbc3d007b9cf76a1c7b54b4d5018..e5b2b8b6137ac7632ad876c4acd2ed8585a40059 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -3465,6 +3465,91 @@ class ResolverVisitor extends MappingVisitor<Element> {
visit(node.expression);
}
+ DartType typeOfConstant(Constant constant) {
+ if (constant.isInt()) return compiler.intClass.rawType;
+ if (constant.isBool()) return compiler.boolClass.rawType;
+ if (constant.isDouble()) return compiler.doubleClass.rawType;
+ if (constant.isString()) return compiler.stringClass.rawType;
+ if (constant.isNull()) return compiler.nullClass.rawType;
+ if (constant.isFunction()) return compiler.functionClass.rawType;
+ assert(constant.isObject());
+ ObjectConstant objectConstant = constant;
+ return objectConstant.type;
+ }
+
+ bool overridesEquals(DartType type) {
+ ClassElement cls = type.element;
+ Element equals = cls.lookupMember('==');
+ return equals.getEnclosingClass() != compiler.objectClass;
+ }
+
+ void checkCaseExpressions(SwitchStatement node) {
+ TargetElement breakElement = getOrCreateTargetElement(node);
+ Map<String, LabelElement> continueLabels = <String, LabelElement>{};
+
+ Link<Node> cases = node.cases.nodes;
+ SwitchCase switchCase = cases.head;
+ CaseMatch firstCase = null;
+ DartType firstCaseType = null;
+ bool hasReportedProblem = false;
+
+ for (Link<Node> cases = node.cases.nodes;
+ !cases.isEmpty;
+ cases = cases.tail) {
+ SwitchCase switchCase = cases.head;
+
+ for (Node labelOrCase in switchCase.labelsAndCases) {
+ CaseMatch caseMatch = labelOrCase.asCaseMatch();
+ if (caseMatch == null) continue;
+
+ // Analyze the constant.
+ Constant constant = mapping.getConstant(caseMatch.expression);
+ assert(invariant(node, constant != null,
+ message: 'No constant computed for $node'));
+
+ DartType caseType = typeOfConstant(constant);
+
+ if (firstCaseType == null) {
+ firstCase = caseMatch;
+ firstCaseType = caseType;
+
+ // We only report the bad type on the first class element. All others
+ // get a "type differs" error.
+ if (caseType.element == compiler.doubleClass) {
+ compiler.reportError(node,
+ MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
+ {'type': "double"});
+ } else if (caseType.element == compiler.functionClass) {
+ compiler.reportError(node, MessageKind.SWITCH_CASE_FORBIDDEN,
+ {'type': "Function"});
+ } else if (constant.isObject() && overridesEquals(caseType)) {
+ compiler.reportError(firstCase.expression,
+ MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
+ {'type': caseType});
+ }
+ } else {
+ if (caseType != firstCaseType) {
+ if (!hasReportedProblem) {
+ compiler.reportError(
+ node,
+ MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
+ {'type': firstCaseType});
+ compiler.reportInfo(
+ firstCase.expression,
+ MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
+ {'type': firstCaseType});
+ hasReportedProblem = true;
+ }
+ compiler.reportInfo(
+ caseMatch.expression,
+ MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
+ {'type': caseType});
+ }
+ }
+ }
+ }
+ }
+
visitSwitchStatement(SwitchStatement node) {
node.expression.accept(this);
@@ -3516,6 +3601,10 @@ class ResolverVisitor extends MappingVisitor<Element> {
}
}
+ addDeferredAction(enclosingElement, () {
+ checkCaseExpressions(node);
+ });
+
statementScope.enterSwitch(breakElement, continueLabels);
node.cases.accept(this);
statementScope.exitSwitch();
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/typechecker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698