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

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: Address comments. (500) 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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/typechecker.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.rawType;
3470 if (constant.isBool()) return compiler.boolClass.rawType;
3471 if (constant.isDouble()) return compiler.doubleClass.rawType;
3472 if (constant.isString()) return compiler.stringClass.rawType;
3473 if (constant.isNull()) return compiler.nullClass.rawType;
3474 if (constant.isFunction()) return compiler.functionClass.rawType;
3475 assert(constant.isObject());
3476 ObjectConstant objectConstant = constant;
3477 return objectConstant.type;
3478 }
3479
3480 bool overridesEquals(DartType type) {
3481 ClassElement cls = type.element;
3482 Element equals = cls.lookupMember('==');
3483 return equals.getEnclosingClass() != compiler.objectClass;
3484 }
3485
3486 void checkCaseExpressions(SwitchStatement node) {
3487 TargetElement breakElement = getOrCreateTargetElement(node);
3488 Map<String, LabelElement> continueLabels = <String, LabelElement>{};
3489
3490 Link<Node> cases = node.cases.nodes;
3491 SwitchCase switchCase = cases.head;
3492 CaseMatch firstCase = null;
3493 DartType firstCaseType = null;
3494 bool hasReportedProblem = false;
3495
3496 for (Link<Node> cases = node.cases.nodes;
3497 !cases.isEmpty;
3498 cases = cases.tail) {
3499 SwitchCase switchCase = cases.head;
3500
3501 for (Node labelOrCase in switchCase.labelsAndCases) {
3502 CaseMatch caseMatch = labelOrCase.asCaseMatch();
3503 if (caseMatch == null) continue;
3504
3505 // Analyze the constant.
3506 Constant constant = mapping.getConstant(caseMatch.expression);
3507 assert(invariant(node, constant != null,
3508 message: 'No constant computed for $node'));
3509
3510 DartType caseType = typeOfConstant(constant);
3511
3512 if (firstCaseType == null) {
3513 firstCase = caseMatch;
3514 firstCaseType = caseType;
3515
3516 // We only report the bad type on the first class element. All others
3517 // get a "type differs" error.
3518 if (caseType.element == compiler.doubleClass) {
3519 compiler.reportError(node,
3520 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
3521 {'type': "double"});
3522 } else if (caseType.element == compiler.functionClass) {
3523 compiler.reportError(node, MessageKind.SWITCH_CASE_FORBIDDEN,
3524 {'type': "Function"});
3525 } else if (constant.isObject() && overridesEquals(caseType)) {
3526 compiler.reportError(firstCase.expression,
3527 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
3528 {'type': caseType});
3529 }
3530 } else {
3531 if (caseType != firstCaseType) {
3532 if (!hasReportedProblem) {
3533 compiler.reportError(
3534 node,
3535 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
3536 {'type': firstCaseType});
3537 compiler.reportInfo(
3538 firstCase.expression,
3539 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
3540 {'type': firstCaseType});
3541 hasReportedProblem = true;
3542 }
3543 compiler.reportInfo(
3544 caseMatch.expression,
3545 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
3546 {'type': caseType});
3547 }
3548 }
3549 }
3550 }
3551 }
3552
3468 visitSwitchStatement(SwitchStatement node) { 3553 visitSwitchStatement(SwitchStatement node) {
3469 node.expression.accept(this); 3554 node.expression.accept(this);
3470 3555
3471 TargetElement breakElement = getOrCreateTargetElement(node); 3556 TargetElement breakElement = getOrCreateTargetElement(node);
3472 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; 3557 Map<String, LabelElement> continueLabels = <String, LabelElement>{};
3473 Link<Node> cases = node.cases.nodes; 3558 Link<Node> cases = node.cases.nodes;
3474 while (!cases.isEmpty) { 3559 while (!cases.isEmpty) {
3475 SwitchCase switchCase = cases.head; 3560 SwitchCase switchCase = cases.head;
3476 for (Node labelOrCase in switchCase.labelsAndCases) { 3561 for (Node labelOrCase in switchCase.labelsAndCases) {
3477 CaseMatch caseMatch = labelOrCase.asCaseMatch(); 3562 CaseMatch caseMatch = labelOrCase.asCaseMatch();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3509 mapping[label] = labelElement; 3594 mapping[label] = labelElement;
3510 continueLabels[labelName] = labelElement; 3595 continueLabels[labelName] = labelElement;
3511 } 3596 }
3512 cases = cases.tail; 3597 cases = cases.tail;
3513 // Test that only the last case, if any, is a default case. 3598 // Test that only the last case, if any, is a default case.
3514 if (switchCase.defaultKeyword != null && !cases.isEmpty) { 3599 if (switchCase.defaultKeyword != null && !cases.isEmpty) {
3515 error(switchCase, MessageKind.INVALID_CASE_DEFAULT); 3600 error(switchCase, MessageKind.INVALID_CASE_DEFAULT);
3516 } 3601 }
3517 } 3602 }
3518 3603
3604 addDeferredAction(enclosingElement, () {
3605 checkCaseExpressions(node);
3606 });
3607
3519 statementScope.enterSwitch(breakElement, continueLabels); 3608 statementScope.enterSwitch(breakElement, continueLabels);
3520 node.cases.accept(this); 3609 node.cases.accept(this);
3521 statementScope.exitSwitch(); 3610 statementScope.exitSwitch();
3522 3611
3523 // Clean-up unused labels. 3612 // Clean-up unused labels.
3524 continueLabels.forEach((String key, LabelElement label) { 3613 continueLabels.forEach((String key, LabelElement label) {
3525 if (!label.isContinueTarget) { 3614 if (!label.isContinueTarget) {
3526 TargetElement targetElement = label.target; 3615 TargetElement targetElement = label.target;
3527 SwitchCase switchCase = targetElement.statement; 3616 SwitchCase switchCase = targetElement.statement;
3528 mapping.remove(switchCase); 3617 mapping.remove(switchCase);
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 return finishConstructorReference(visit(expression), 4633 return finishConstructorReference(visit(expression),
4545 expression, expression); 4634 expression, expression);
4546 } 4635 }
4547 } 4636 }
4548 4637
4549 /// Looks up [name] in [scope] and unwraps the result. 4638 /// Looks up [name] in [scope] and unwraps the result.
4550 Element lookupInScope(Compiler compiler, Node node, 4639 Element lookupInScope(Compiler compiler, Node node,
4551 Scope scope, String name) { 4640 Scope scope, String name) {
4552 return Elements.unwrap(scope.lookup(name), compiler, node); 4641 return Elements.unwrap(scope.lookup(name), compiler, node);
4553 } 4642 }
OLDNEW
« 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