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

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: Rebase 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
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 a5cc401ac61b30e4ca1e198ca9051e9b9348ac47..8222b4a54ce38bb68b3bcf0acc046cae4a18242e 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -3466,6 +3466,92 @@ class ResolverVisitor extends MappingVisitor<Element> {
visit(node.expression);
}
+ DartType typeOfConstant(Constant constant) {
+ if (constant.isInt()) return compiler.intClass.computeType(compiler);
+ if (constant.isBool()) return compiler.boolClass.computeType(compiler);
+ if (constant.isDouble()) return compiler.doubleClass.computeType(compiler);
+ if (constant.isString()) return compiler.stringClass.computeType(compiler);
+ if (constant.isNull()) return compiler.nullClass.computeType(compiler);
+ if (constant.isFunction()) {
+ return compiler.functionClass.computeType(compiler);
+ }
+ 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_FORBIDDEN,
+ {'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);
@@ -3517,6 +3603,10 @@ class ResolverVisitor extends MappingVisitor<Element> {
}
}
+ addDeferredAction(enclosingElement, () {
floitsch 2014/02/28 22:00:27 I need the constants to be evaluated. I'm not sure
+ 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') | tests/co19/co19-dart2js.status » ('J')

Powered by Google App Engine
This is Rietveld 408576698