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

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