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

Side by Side 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: Remove same-type switch-test from type-checker test. Created 6 years, 9 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
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 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element get currentElement; 8 Element get currentElement;
9 Setlet<Node> get superUses; 9 Setlet<Node> get superUses;
10 10
(...skipping 3447 matching lines...) Expand 10 before | Expand all | Expand 10 after
3458 } 3458 }
3459 3459
3460 visitLiteralMapEntry(LiteralMapEntry node) { 3460 visitLiteralMapEntry(LiteralMapEntry node) {
3461 node.visitChildren(this); 3461 node.visitChildren(this);
3462 } 3462 }
3463 3463
3464 visitNamedArgument(NamedArgument node) { 3464 visitNamedArgument(NamedArgument node) {
3465 visit(node.expression); 3465 visit(node.expression);
3466 } 3466 }
3467 3467
3468 DartType typeOfConstant(Constant constant) {
3469 if (constant.isInt()) return compiler.intClass.computeType(compiler);
karlklose 2014/03/03 10:38:05 These should use `rawType` instead of `computeType
floitsch 2014/03/03 18:47:16 Done.
3470 if (constant.isBool()) return compiler.boolClass.computeType(compiler);
3471 if (constant.isDouble()) return compiler.doubleClass.computeType(compiler);
3472 if (constant.isString()) return compiler.stringClass.computeType(compiler);
3473 if (constant.isNull()) return compiler.nullClass.computeType(compiler);
3474 if (constant.isFunction()) {
3475 return compiler.functionClass.computeType(compiler);
karlklose 2014/03/03 10:38:05 Ditto.
floitsch 2014/03/03 18:47:16 Done.
3476 }
3477 assert(constant.isObject());
3478 ObjectConstant objectConstant = constant;
3479 return objectConstant.type;
3480 }
3481
3482 bool overridesEquals(DartType type) {
3483 ClassElement cls = type.element;
3484 Element equals = cls.lookupMember('==');
3485 return equals.getEnclosingClass() != compiler.objectClass;
3486 }
3487
3488 void checkCaseExpressions(SwitchStatement node) {
3489 TargetElement breakElement = getOrCreateTargetElement(node);
3490 Map<String, LabelElement> continueLabels = <String, LabelElement>{};
3491
3492 Link<Node> cases = node.cases.nodes;
3493 SwitchCase switchCase = cases.head;
3494 CaseMatch firstCase = null;
3495 DartType firstCaseType = null;
3496 bool hasReportedProblem = false;
3497
3498 for (Link<Node> cases = node.cases.nodes;
3499 !cases.isEmpty;
3500 cases = cases.tail) {
3501 SwitchCase switchCase = cases.head;
3502
3503 for (Node labelOrCase in switchCase.labelsAndCases) {
3504 CaseMatch caseMatch = labelOrCase.asCaseMatch();
3505 if (caseMatch == null) continue;
3506
3507 // Analyze the constant.
3508 Constant constant = mapping.getConstant(caseMatch.expression);
3509 assert(invariant(node, constant != null,
3510 message: 'No constant computed for $node'));
3511
3512 DartType caseType = typeOfConstant(constant);
3513
3514 if (firstCaseType == null) {
3515 firstCase = caseMatch;
3516 firstCaseType = caseType;
3517
3518 // We only report the bad type on the first class element. All others
3519 // get a "type differs" error.
3520 if (caseType.element == compiler.doubleClass) {
3521 compiler.reportError(node, MessageKind.SWITCH_CASE_FORBIDDEN,
karlklose 2014/03/03 10:38:05 Is the problem here that double implements '=='?
floitsch 2014/03/03 18:47:16 Reusing OVERRIDES_EQUALS.
3522 {'type': "double"});
3523 } else if (caseType.element == compiler.functionClass) {
3524 compiler.reportError(node, MessageKind.SWITCH_CASE_FORBIDDEN,
3525 {'type': "Function"});
3526 } else if (constant.isObject() && overridesEquals(caseType)) {
3527 compiler.reportError(firstCase.expression,
3528 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
3529 {'type': caseType});
3530 }
3531 } else {
3532 if (caseType != firstCaseType) {
3533 if (!hasReportedProblem) {
3534 compiler.reportError(
3535 node,
3536 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
3537 {'type': firstCaseType});
3538 compiler.reportInfo(
3539 firstCase.expression,
3540 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
3541 {'type': firstCaseType});
3542 hasReportedProblem = true;
3543 }
3544 compiler.reportInfo(
3545 caseMatch.expression,
3546 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
3547 {'type': caseType});
3548 }
3549 }
3550 }
3551 }
3552 }
3553
3468 visitSwitchStatement(SwitchStatement node) { 3554 visitSwitchStatement(SwitchStatement node) {
3469 node.expression.accept(this); 3555 node.expression.accept(this);
3470 3556
3471 TargetElement breakElement = getOrCreateTargetElement(node); 3557 TargetElement breakElement = getOrCreateTargetElement(node);
3472 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; 3558 Map<String, LabelElement> continueLabels = <String, LabelElement>{};
3473 Link<Node> cases = node.cases.nodes; 3559 Link<Node> cases = node.cases.nodes;
3474 while (!cases.isEmpty) { 3560 while (!cases.isEmpty) {
3475 SwitchCase switchCase = cases.head; 3561 SwitchCase switchCase = cases.head;
3476 for (Node labelOrCase in switchCase.labelsAndCases) { 3562 for (Node labelOrCase in switchCase.labelsAndCases) {
3477 CaseMatch caseMatch = labelOrCase.asCaseMatch(); 3563 CaseMatch caseMatch = labelOrCase.asCaseMatch();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3509 mapping[label] = labelElement; 3595 mapping[label] = labelElement;
3510 continueLabels[labelName] = labelElement; 3596 continueLabels[labelName] = labelElement;
3511 } 3597 }
3512 cases = cases.tail; 3598 cases = cases.tail;
3513 // Test that only the last case, if any, is a default case. 3599 // Test that only the last case, if any, is a default case.
3514 if (switchCase.defaultKeyword != null && !cases.isEmpty) { 3600 if (switchCase.defaultKeyword != null && !cases.isEmpty) {
3515 error(switchCase, MessageKind.INVALID_CASE_DEFAULT); 3601 error(switchCase, MessageKind.INVALID_CASE_DEFAULT);
3516 } 3602 }
3517 } 3603 }
3518 3604
3605 addDeferredAction(enclosingElement, () {
3606 checkCaseExpressions(node);
3607 });
3608
3519 statementScope.enterSwitch(breakElement, continueLabels); 3609 statementScope.enterSwitch(breakElement, continueLabels);
3520 node.cases.accept(this); 3610 node.cases.accept(this);
3521 statementScope.exitSwitch(); 3611 statementScope.exitSwitch();
3522 3612
3523 // Clean-up unused labels. 3613 // Clean-up unused labels.
3524 continueLabels.forEach((String key, LabelElement label) { 3614 continueLabels.forEach((String key, LabelElement label) {
3525 if (!label.isContinueTarget) { 3615 if (!label.isContinueTarget) {
3526 TargetElement targetElement = label.target; 3616 TargetElement targetElement = label.target;
3527 SwitchCase switchCase = targetElement.statement; 3617 SwitchCase switchCase = targetElement.statement;
3528 mapping.remove(switchCase); 3618 mapping.remove(switchCase);
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 return finishConstructorReference(visit(expression), 4634 return finishConstructorReference(visit(expression),
4545 expression, expression); 4635 expression, expression);
4546 } 4636 }
4547 } 4637 }
4548 4638
4549 /// Looks up [name] in [scope] and unwraps the result. 4639 /// Looks up [name] in [scope] and unwraps the result.
4550 Element lookupInScope(Compiler compiler, Node node, 4640 Element lookupInScope(Compiler compiler, Node node,
4551 Scope scope, String name) { 4641 Scope scope, String name) {
4552 return Elements.unwrap(scope.lookup(name), compiler, node); 4642 return Elements.unwrap(scope.lookup(name), compiler, node);
4553 } 4643 }
OLDNEW
« 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