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

Side by Side Diff: pkg/compiler/lib/src/typechecker.dart

Issue 2595583002: Remove StatementType (Closed)
Patch Set: Created 4 years 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
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 library dart2js.typechecker; 5 library dart2js.typechecker;
6 6
7 import 'common/names.dart' show Identifiers; 7 import 'common/names.dart' show Identifiers;
8 import 'common/resolution.dart' show Resolution; 8 import 'common/resolution.dart' show Resolution;
9 import 'common/tasks.dart' show CompilerTask; 9 import 'common/tasks.dart' show CompilerTask;
10 import 'common.dart'; 10 import 'common.dart';
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 } 423 }
424 return type; 424 return type;
425 } 425 }
426 426
427 DartType analyzeWithDefault(Node node, DartType defaultValue) { 427 DartType analyzeWithDefault(Node node, DartType defaultValue) {
428 return node != null ? analyze(node) : defaultValue; 428 return node != null ? analyze(node) : defaultValue;
429 } 429 }
430 430
431 /// If [inInitializer] is true, assignment should be interpreted as write to 431 /// If [inInitializer] is true, assignment should be interpreted as write to
432 /// a field and not to a setter. 432 /// a field and not to a setter.
433 DartType analyze(Node node, {bool inInitializer: false}) { 433 DartType analyze(Node node,
434 {bool inInitializer: false, bool mustHaveType: true}) {
434 if (node == null) { 435 if (node == null) {
435 final String error = 'Unexpected node: null'; 436 final String error = 'Unexpected node: null';
436 if (lastSeenNode != null) { 437 if (lastSeenNode != null) {
437 reporter.internalError(lastSeenNode, error); 438 reporter.internalError(lastSeenNode, error);
438 } else { 439 } else {
439 reporter.internalError(executableContext, error); 440 reporter.internalError(executableContext, error);
440 } 441 }
441 } else { 442 } else {
442 lastSeenNode = node; 443 lastSeenNode = node;
443 } 444 }
444 bool previouslyInitializer = analyzingInitializer; 445 bool previouslyInitializer = analyzingInitializer;
445 analyzingInitializer = inInitializer; 446 analyzingInitializer = inInitializer;
446 DartType result = node.accept(this); 447 DartType result = node.accept(this);
447 analyzingInitializer = previouslyInitializer; 448 analyzingInitializer = previouslyInitializer;
448 if (result == null) { 449 if (result == null && mustHaveType) {
449 reporter.internalError(node, 'Type is null.'); 450 reporter.internalError(node, 'Type is null.');
450 } 451 }
451 return result; 452 return result;
452 } 453 }
453 454
455 void analyzeNode(Node node, {bool inInitializer: false}) {
Siggi Cherem (dart-lang) 2016/12/20 20:58:42 nit: consider renaming this? someone may naively c
Johnni Winther 2016/12/21 09:32:43 Renamed to analyzeUntyped
456 if (node != null) {
457 analyze(node, inInitializer: inInitializer, mustHaveType: false);
458 }
459 }
460
454 void checkTypePromotion(Node node, TypePromotion typePromotion, 461 void checkTypePromotion(Node node, TypePromotion typePromotion,
455 {bool checkAccesses: false}) { 462 {bool checkAccesses: false}) {
456 VariableElement variable = typePromotion.variable; 463 VariableElement variable = typePromotion.variable;
457 String variableName = variable.name; 464 String variableName = variable.name;
458 List<Node> potentialMutationsIn = 465 List<Node> potentialMutationsIn =
459 elements.getPotentialMutationsIn(node, variable); 466 elements.getPotentialMutationsIn(node, variable);
460 if (!potentialMutationsIn.isEmpty) { 467 if (!potentialMutationsIn.isEmpty) {
461 DiagnosticMessage hint = reporter.createMessage( 468 DiagnosticMessage hint = reporter.createMessage(
462 typePromotion.node, 469 typePromotion.node,
463 MessageKind.POTENTIAL_MUTATION, 470 MessageKind.POTENTIAL_MUTATION,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 } 530 }
524 531
525 for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) { 532 for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) {
526 typePromotion = typePromotion.copy(); 533 typePromotion = typePromotion.copy();
527 checkTypePromotion(right, typePromotion); 534 checkTypePromotion(right, typePromotion);
528 showTypePromotion(node, typePromotion); 535 showTypePromotion(node, typePromotion);
529 } 536 }
530 } 537 }
531 538
532 /// Analyze [node] in the context of the known types shown in [context]. 539 /// Analyze [node] in the context of the known types shown in [context].
533 DartType analyzeInPromotedContext(Node context, Node node) { 540 DartType analyzeInPromotedContext(Node context, Node node,
541 {bool mustHaveType: false}) {
534 Link<TypePromotion> knownForNode = const Link<TypePromotion>(); 542 Link<TypePromotion> knownForNode = const Link<TypePromotion>();
535 for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) { 543 for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) {
536 typePromotion = typePromotion.copy(); 544 typePromotion = typePromotion.copy();
537 checkTypePromotion(node, typePromotion, checkAccesses: true); 545 checkTypePromotion(node, typePromotion, checkAccesses: true);
538 knownForNode = knownForNode.prepend(typePromotion); 546 knownForNode = knownForNode.prepend(typePromotion);
539 registerKnownTypePromotion(typePromotion); 547 registerKnownTypePromotion(typePromotion);
540 } 548 }
541 549
542 final DartType type = analyze(node); 550 final DartType type = analyze(node, mustHaveType: mustHaveType);
543 551
544 while (!knownForNode.isEmpty) { 552 while (!knownForNode.isEmpty) {
545 unregisterKnownTypePromotion(knownForNode.head); 553 unregisterKnownTypePromotion(knownForNode.head);
546 knownForNode = knownForNode.tail; 554 knownForNode = knownForNode.tail;
547 } 555 }
548 556
549 return type; 557 return type;
550 } 558 }
551 559
552 /** 560 /**
(...skipping 23 matching lines...) Expand all
576 void pushCascadeType(DartType type) { 584 void pushCascadeType(DartType type) {
577 cascadeTypes = cascadeTypes.prepend(type); 585 cascadeTypes = cascadeTypes.prepend(type);
578 } 586 }
579 587
580 DartType popCascadeType() { 588 DartType popCascadeType() {
581 DartType type = cascadeTypes.head; 589 DartType type = cascadeTypes.head;
582 cascadeTypes = cascadeTypes.tail; 590 cascadeTypes = cascadeTypes.tail;
583 return type; 591 return type;
584 } 592 }
585 593
586 DartType visitAssert(Assert node) { 594 visitAssert(Assert node) {
587 analyze(node.condition); 595 analyze(node.condition);
588 if (node.hasMessage) analyze(node.message); 596 if (node.hasMessage) analyze(node.message);
589 return const StatementType();
590 } 597 }
591 598
592 DartType visitBlock(Block node) { 599 visitBlock(Block node) {
593 return analyze(node.statements); 600 analyzeNode(node.statements);
594 } 601 }
595 602
596 DartType visitCascade(Cascade node) { 603 DartType visitCascade(Cascade node) {
597 analyze(node.expression); 604 analyze(node.expression);
598 return popCascadeType(); 605 return popCascadeType();
599 } 606 }
600 607
601 DartType visitCascadeReceiver(CascadeReceiver node) { 608 DartType visitCascadeReceiver(CascadeReceiver node) {
602 DartType type = analyze(node.expression); 609 DartType type = analyze(node.expression);
603 pushCascadeType(type); 610 pushCascadeType(type);
604 return type; 611 return type;
605 } 612 }
606 613
607 DartType visitDoWhile(DoWhile node) { 614 visitDoWhile(DoWhile node) {
608 analyze(node.body); 615 analyzeNode(node.body);
609 checkCondition(node.condition); 616 checkCondition(node.condition);
610 return const StatementType();
611 } 617 }
612 618
613 DartType visitExpressionStatement(ExpressionStatement node) { 619 visitExpressionStatement(ExpressionStatement node) {
614 Expression expression = node.expression; 620 Expression expression = node.expression;
615 analyze(expression); 621 analyze(expression);
616 return const StatementType();
617 } 622 }
618 623
619 /** Dart Programming Language Specification: 11.5.1 For Loop */ 624 /** Dart Programming Language Specification: 11.5.1 For Loop */
620 DartType visitFor(For node) { 625 visitFor(For node) {
621 if (node.initializer != null) { 626 if (node.initializer != null) {
622 analyze(node.initializer); 627 analyzeNode(node.initializer);
623 } 628 }
624 if (node.condition != null) { 629 if (node.condition != null) {
625 checkCondition(node.condition); 630 checkCondition(node.condition);
626 } 631 }
627 if (node.update != null) { 632 if (node.update != null) {
628 analyze(node.update); 633 analyzeNode(node.update);
629 } 634 }
630 return analyze(node.body); 635 analyzeNode(node.body);
631 } 636 }
632 637
633 DartType visitFunctionDeclaration(FunctionDeclaration node) { 638 visitFunctionDeclaration(FunctionDeclaration node) {
634 analyze(node.function); 639 analyze(node.function);
635 return const StatementType();
636 } 640 }
637 641
638 DartType visitFunctionExpression(FunctionExpression node) { 642 DartType visitFunctionExpression(FunctionExpression node) {
639 DartType type; 643 DartType type;
640 DartType returnType; 644 DartType returnType;
641 final FunctionElement element = elements.getFunctionDefinition(node); 645 final FunctionElement element = elements.getFunctionDefinition(node);
642 assert(invariant(node, element != null, 646 assert(invariant(node, element != null,
643 message: 'FunctionExpression with no element')); 647 message: 'FunctionExpression with no element'));
644 if (Elements.isUnresolved(element)) return const DynamicType(); 648 if (Elements.isUnresolved(element)) return const DynamicType();
645 if (element.isGenerativeConstructor) { 649 if (element.isGenerativeConstructor) {
646 type = const DynamicType(); 650 type = const DynamicType();
647 returnType = const VoidType(); 651 returnType = const VoidType();
648 652
649 element.functionSignature.forEachParameter((ParameterElement parameter) { 653 element.functionSignature.forEachParameter((ParameterElement parameter) {
650 if (parameter.isInitializingFormal) { 654 if (parameter.isInitializingFormal) {
651 InitializingFormalElement fieldParameter = parameter; 655 InitializingFormalElement fieldParameter = parameter;
652 checkAssignable(parameter, parameter.type, 656 checkAssignable(parameter, parameter.type,
653 fieldParameter.fieldElement.computeType(resolution)); 657 fieldParameter.fieldElement.computeType(resolution));
654 } 658 }
655 }); 659 });
656 if (node.initializers != null) { 660 if (node.initializers != null) {
657 analyze(node.initializers, inInitializer: true); 661 analyzeNode(node.initializers, inInitializer: true);
658 } 662 }
659 } else { 663 } else {
660 FunctionType functionType = element.computeType(resolution); 664 FunctionType functionType = element.computeType(resolution);
661 returnType = functionType.returnType; 665 returnType = functionType.returnType;
662 type = functionType; 666 type = functionType;
663 } 667 }
664 ExecutableElement previousExecutableContext = executableContext; 668 ExecutableElement previousExecutableContext = executableContext;
665 DartType previousReturnType = expectedReturnType; 669 DartType previousReturnType = expectedReturnType;
666 expectedReturnType = returnType; 670 expectedReturnType = returnType;
667 AsyncMarker previousAsyncMarker = currentAsyncMarker; 671 AsyncMarker previousAsyncMarker = currentAsyncMarker;
668 672
669 executableContext = element; 673 executableContext = element;
670 currentAsyncMarker = element.asyncMarker; 674 currentAsyncMarker = element.asyncMarker;
671 analyze(node.body); 675 analyzeNode(node.body);
672 676
673 executableContext = previousExecutableContext; 677 executableContext = previousExecutableContext;
674 expectedReturnType = previousReturnType; 678 expectedReturnType = previousReturnType;
675 currentAsyncMarker = previousAsyncMarker; 679 currentAsyncMarker = previousAsyncMarker;
676 return type; 680 return type;
677 } 681 }
678 682
679 DartType visitIdentifier(Identifier node) { 683 DartType visitIdentifier(Identifier node) {
680 if (node.isThis()) { 684 if (node.isThis()) {
681 return thisType; 685 return thisType;
682 } else if (node.isSuper()) { 686 } else if (node.isSuper()) {
683 return superType; 687 return superType;
684 } else { 688 } else {
685 TypedElement element = elements[node]; 689 TypedElement element = elements[node];
686 assert(invariant(node, element != null, 690 assert(invariant(node, element != null,
687 message: 'Missing element for identifier')); 691 message: 'Missing element for identifier'));
688 assert(invariant( 692 assert(invariant(
689 node, element.isVariable || element.isParameter || element.isField, 693 node, element.isVariable || element.isParameter || element.isField,
690 message: 'Unexpected context element ${element}')); 694 message: 'Unexpected context element ${element}'));
691 return element.computeType(resolution); 695 return element.computeType(resolution);
692 } 696 }
693 } 697 }
694 698
695 DartType visitIf(If node) { 699 visitIf(If node) {
696 Expression condition = node.condition.expression; 700 Expression condition = node.condition.expression;
697 Statement thenPart = node.thenPart; 701 Statement thenPart = node.thenPart;
698 702
699 checkCondition(node.condition); 703 checkCondition(node.condition);
700 analyzeInPromotedContext(condition, thenPart); 704 analyzeInPromotedContext(condition, thenPart, mustHaveType: false);
Siggi Cherem (dart-lang) 2016/12/20 20:58:42 The default value is also false. Did you mean to k
Johnni Winther 2016/12/21 10:25:02 Default value should have been `true`.
701 if (node.elsePart != null) { 705 if (node.elsePart != null) {
702 analyze(node.elsePart); 706 analyzeNode(node.elsePart);
703 } 707 }
704 return const StatementType();
705 } 708 }
706 709
707 void checkPrivateAccess(Node node, Element element, String name) { 710 void checkPrivateAccess(Node node, Element element, String name) {
708 if (name != null && 711 if (name != null &&
709 Name.isPrivateName(name) && 712 Name.isPrivateName(name) &&
710 element.library != currentLibrary) { 713 element.library != currentLibrary) {
711 reportTypeWarning(node, MessageKind.PRIVATE_ACCESS, 714 reportTypeWarning(node, MessageKind.PRIVATE_ACCESS,
712 {'name': name, 'libraryName': element.library.libraryOrScriptName}); 715 {'name': name, 'libraryName': element.library.libraryOrScriptName});
713 } 716 }
714 } 717 }
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 !link.isEmpty; 1648 !link.isEmpty;
1646 link = link.tail) { 1649 link = link.tail) {
1647 Node element = link.head; 1650 Node element = link.head;
1648 DartType elementType = analyze(element); 1651 DartType elementType = analyze(element);
1649 checkAssignable(element, elementType, listElementType, 1652 checkAssignable(element, elementType, listElementType,
1650 isConst: node.isConst); 1653 isConst: node.isConst);
1651 } 1654 }
1652 return listType; 1655 return listType;
1653 } 1656 }
1654 1657
1655 DartType visitNodeList(NodeList node) { 1658 visitNodeList(NodeList node) {
1656 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { 1659 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
1657 analyze(link.head, inInitializer: analyzingInitializer); 1660 analyzeNode(link.head, inInitializer: analyzingInitializer);
Siggi Cherem (dart-lang) 2016/12/20 20:58:42 is it always the case that node-lists are used onl
Johnni Winther 2016/12/21 10:25:02 No, but we don't need the individual types, anyway
1658 } 1661 }
1659 return const StatementType();
1660 } 1662 }
1661 1663
1662 DartType visitRedirectingFactoryBody(RedirectingFactoryBody node) { 1664 visitRedirectingFactoryBody(RedirectingFactoryBody node) {
1663 // TODO(lrn): Typecheck the body. It must refer to the constructor 1665 // TODO(lrn): Typecheck the body. It must refer to the constructor
1664 // of a subtype. 1666 // of a subtype.
1665 return const StatementType();
1666 } 1667 }
1667 1668
1668 DartType visitRethrow(Rethrow node) { 1669 visitRethrow(Rethrow node) {
1669 return const StatementType(); 1670 // Nothing to do here.
1670 } 1671 }
1671 1672
1672 /** Dart Programming Language Specification: 11.10 Return */ 1673 /** Dart Programming Language Specification: 11.10 Return */
1673 DartType visitReturn(Return node) { 1674 visitReturn(Return node) {
1674 if (identical(node.beginToken.stringValue, 'native')) { 1675 if (identical(node.beginToken.stringValue, 'native')) {
1675 return const StatementType(); 1676 return;
1676 } 1677 }
1677 1678
1678 final Node expression = node.expression; 1679 final Node expression = node.expression;
1679 1680
1680 // Executing a return statement return e; [...] It is a static type warning 1681 // Executing a return statement return e; [...] It is a static type warning
1681 // if the type of e may not be assigned to the declared return type of the 1682 // if the type of e may not be assigned to the declared return type of the
1682 // immediately enclosing function. 1683 // immediately enclosing function.
1683 if (expression != null) { 1684 if (expression != null) {
1684 DartType expressionType = analyze(expression); 1685 DartType expressionType = analyze(expression);
1685 if (executableContext.isGenerativeConstructor) { 1686 if (executableContext.isGenerativeConstructor) {
(...skipping 14 matching lines...) Expand all
1700 // `return;` is allowed. 1701 // `return;` is allowed.
1701 } else if (!types.isAssignable(expectedReturnType, const VoidType())) { 1702 } else if (!types.isAssignable(expectedReturnType, const VoidType())) {
1702 // Let f be the function immediately enclosing a return statement of the 1703 // Let f be the function immediately enclosing a return statement of the
1703 // form 'return;' It is a static warning if both of the following 1704 // form 'return;' It is a static warning if both of the following
1704 // conditions hold: 1705 // conditions hold:
1705 // - f is not a generative constructor. 1706 // - f is not a generative constructor.
1706 // - The return type of f may not be assigned to void. 1707 // - The return type of f may not be assigned to void.
1707 reportTypeWarning( 1708 reportTypeWarning(
1708 node, MessageKind.RETURN_NOTHING, {'returnType': expectedReturnType}); 1709 node, MessageKind.RETURN_NOTHING, {'returnType': expectedReturnType});
1709 } 1710 }
1710 return const StatementType();
1711 } 1711 }
1712 1712
1713 DartType visitThrow(Throw node) { 1713 DartType visitThrow(Throw node) {
1714 // TODO(johnniwinther): Handle reachability. 1714 // TODO(johnniwinther): Handle reachability.
1715 analyze(node.expression); 1715 analyze(node.expression);
1716 return const DynamicType(); 1716 return const DynamicType();
1717 } 1717 }
1718 1718
1719 DartType visitAwait(Await node) { 1719 DartType visitAwait(Await node) {
1720 DartType expressionType = analyze(node.expression); 1720 DartType expressionType = analyze(node.expression);
(...skipping 16 matching lines...) Expand all
1737 if (currentAsyncMarker.isAsync) { 1737 if (currentAsyncMarker.isAsync) {
1738 // The static type of expression must be assignable to Stream. 1738 // The static type of expression must be assignable to Stream.
1739 checkAssignable(node, resultType, commonElements.streamType()); 1739 checkAssignable(node, resultType, commonElements.streamType());
1740 } else { 1740 } else {
1741 // The static type of expression must be assignable to Iterable. 1741 // The static type of expression must be assignable to Iterable.
1742 checkAssignable(node, resultType, commonElements.iterableType()); 1742 checkAssignable(node, resultType, commonElements.iterableType());
1743 } 1743 }
1744 } 1744 }
1745 // The static type of the result must be assignable to the declared type. 1745 // The static type of the result must be assignable to the declared type.
1746 checkAssignable(node, resultType, expectedReturnType); 1746 checkAssignable(node, resultType, expectedReturnType);
1747 return const StatementType();
1748 } 1747 }
1749 1748
1750 DartType visitTypeAnnotation(TypeAnnotation node) { 1749 DartType visitTypeAnnotation(TypeAnnotation node) {
1751 return elements.getType(node); 1750 return elements.getType(node);
1752 } 1751 }
1753 1752
1754 DartType analyzeVariableTypeAnnotation(VariableDefinitions node) { 1753 DartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
1755 DartType type = analyzeWithDefault(node.type, const DynamicType()); 1754 DartType type = analyzeWithDefault(node.type, const DynamicType());
1756 if (type.isVoid) { 1755 if (type.isVoid) {
1757 reportTypeWarning(node.type, MessageKind.VOID_VARIABLE); 1756 reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
1758 type = const DynamicType(); 1757 type = const DynamicType();
1759 } 1758 }
1760 return type; 1759 return type;
1761 } 1760 }
1762 1761
1763 void analyzeVariableInitializer( 1762 void analyzeVariableInitializer(
1764 Spannable spannable, DartType declaredType, Node initializer) { 1763 Spannable spannable, DartType declaredType, Node initializer) {
1765 if (initializer == null) return; 1764 if (initializer == null) return;
1766 1765
1767 DartType expressionType = analyzeNonVoid(initializer); 1766 DartType expressionType = analyzeNonVoid(initializer);
1768 checkAssignable(spannable, expressionType, declaredType); 1767 checkAssignable(spannable, expressionType, declaredType);
1769 } 1768 }
1770 1769
1771 DartType visitVariableDefinitions(VariableDefinitions node) { 1770 visitVariableDefinitions(VariableDefinitions node) {
1772 DartType type = analyzeVariableTypeAnnotation(node); 1771 DartType type = analyzeVariableTypeAnnotation(node);
1773 for (Link<Node> link = node.definitions.nodes; 1772 for (Link<Node> link = node.definitions.nodes;
1774 !link.isEmpty; 1773 !link.isEmpty;
1775 link = link.tail) { 1774 link = link.tail) {
1776 Node definition = link.head; 1775 Node definition = link.head;
1777 invariant(definition, definition is Identifier || definition is SendSet, 1776 invariant(definition, definition is Identifier || definition is SendSet,
1778 message: 'expected identifier or initialization'); 1777 message: 'expected identifier or initialization');
1779 if (definition is SendSet) { 1778 if (definition is SendSet) {
1780 SendSet initialization = definition; 1779 SendSet initialization = definition;
1781 analyzeVariableInitializer(initialization.assignmentOperator, type, 1780 analyzeVariableInitializer(initialization.assignmentOperator, type,
1782 initialization.arguments.head); 1781 initialization.arguments.head);
1783 // TODO(sigmund): explore inferring a type for `var` using the RHS (like 1782 // TODO(sigmund): explore inferring a type for `var` using the RHS (like
1784 // DDC does), for example: 1783 // DDC does), for example:
1785 // if (node.type == null && node.modifiers.isVar && 1784 // if (node.type == null && node.modifiers.isVar &&
1786 // !initializer.isDynamic) { 1785 // !initializer.isDynamic) {
1787 // var variable = elements[definition]; 1786 // var variable = elements[definition];
1788 // if (variable != null) { 1787 // if (variable != null) {
1789 // var typePromotion = new TypePromotion( 1788 // var typePromotion = new TypePromotion(
1790 // node, variable, initializer); 1789 // node, variable, initializer);
1791 // registerKnownTypePromotion(typePromotion); 1790 // registerKnownTypePromotion(typePromotion);
1792 // } 1791 // }
1793 // } 1792 // }
1794 } 1793 }
1795 } 1794 }
1796 return const StatementType();
1797 } 1795 }
1798 1796
1799 DartType visitWhile(While node) { 1797 visitWhile(While node) {
1800 checkCondition(node.condition); 1798 checkCondition(node.condition);
1801 analyze(node.body); 1799 analyzeNode(node.body);
1802 return const StatementType();
1803 } 1800 }
1804 1801
1805 DartType visitParenthesizedExpression(ParenthesizedExpression node) { 1802 DartType visitParenthesizedExpression(ParenthesizedExpression node) {
1806 Expression expression = node.expression; 1803 Expression expression = node.expression;
1807 DartType type = analyze(expression); 1804 DartType type = analyze(expression);
1808 for (TypePromotion typePromotion in getShownTypePromotionsFor(expression)) { 1805 for (TypePromotion typePromotion in getShownTypePromotionsFor(expression)) {
1809 showTypePromotion(node, typePromotion); 1806 showTypePromotion(node, typePromotion);
1810 } 1807 }
1811 return type; 1808 return type;
1812 } 1809 }
(...skipping 14 matching lines...) Expand all
1827 node.visitChildren(this); 1824 node.visitChildren(this);
1828 return stringType; 1825 return stringType;
1829 } 1826 }
1830 1827
1831 visitStringInterpolationPart(StringInterpolationPart node) { 1828 visitStringInterpolationPart(StringInterpolationPart node) {
1832 node.visitChildren(this); 1829 node.visitChildren(this);
1833 return stringType; 1830 return stringType;
1834 } 1831 }
1835 1832
1836 visitEmptyStatement(EmptyStatement node) { 1833 visitEmptyStatement(EmptyStatement node) {
1837 return const StatementType(); 1834 // Nothing to do here.
1838 } 1835 }
1839 1836
1840 visitBreakStatement(BreakStatement node) { 1837 visitBreakStatement(BreakStatement node) {
1841 return const StatementType(); 1838 // Nothing to do here.
1842 } 1839 }
1843 1840
1844 visitContinueStatement(ContinueStatement node) { 1841 visitContinueStatement(ContinueStatement node) {
1845 return const StatementType(); 1842 // Nothing to do here.
1846 } 1843 }
1847 1844
1848 DartType computeForInElementType(ForIn node) { 1845 DartType computeForInElementType(ForIn node) {
1849 VariableDefinitions declaredIdentifier = 1846 VariableDefinitions declaredIdentifier =
1850 node.declaredIdentifier.asVariableDefinitions(); 1847 node.declaredIdentifier.asVariableDefinitions();
1851 if (declaredIdentifier != null) { 1848 if (declaredIdentifier != null) {
1852 return analyzeWithDefault(declaredIdentifier.type, const DynamicType()); 1849 return analyzeWithDefault(declaredIdentifier.type, const DynamicType());
1853 } else { 1850 } else {
1854 return analyze(node.declaredIdentifier); 1851 return analyze(node.declaredIdentifier);
1855 } 1852 }
(...skipping 24 matching lines...) Expand all
1880 'currentType': streamElementType, 1877 'currentType': streamElementType,
1881 'expressionType': expressionType, 1878 'expressionType': expressionType,
1882 'elementType': elementType 1879 'elementType': elementType
1883 }, 1880 },
1884 isHint: true); 1881 isHint: true);
1885 } 1882 }
1886 } 1883 }
1887 } 1884 }
1888 } 1885 }
1889 } 1886 }
1890 analyze(node.body); 1887 analyzeNode(node.body);
1891 return const StatementType();
1892 } 1888 }
1893 1889
1894 visitSyncForIn(SyncForIn node) { 1890 visitSyncForIn(SyncForIn node) {
1895 DartType elementType = computeForInElementType(node); 1891 DartType elementType = computeForInElementType(node);
1896 DartType expressionType = analyze(node.expression); 1892 DartType expressionType = analyze(node.expression);
1897 DartType iteratorType = lookupMemberType(node.expression, expressionType, 1893 DartType iteratorType = lookupMemberType(node.expression, expressionType,
1898 Identifiers.iterator, MemberKind.GETTER); 1894 Identifiers.iterator, MemberKind.GETTER);
1899 DartType currentType = lookupMemberType( 1895 DartType currentType = lookupMemberType(
1900 node.expression, iteratorType, Identifiers.current, MemberKind.GETTER, 1896 node.expression, iteratorType, Identifiers.current, MemberKind.GETTER,
1901 isHint: true); 1897 isHint: true);
1902 if (!types.isAssignable(currentType, elementType)) { 1898 if (!types.isAssignable(currentType, elementType)) {
1903 reportMessage( 1899 reportMessage(
1904 node.expression, 1900 node.expression,
1905 MessageKind.FORIN_NOT_ASSIGNABLE, 1901 MessageKind.FORIN_NOT_ASSIGNABLE,
1906 { 1902 {
1907 'currentType': currentType, 1903 'currentType': currentType,
1908 'expressionType': expressionType, 1904 'expressionType': expressionType,
1909 'elementType': elementType 1905 'elementType': elementType
1910 }, 1906 },
1911 isHint: true); 1907 isHint: true);
1912 } 1908 }
1913 analyze(node.body); 1909 analyzeNode(node.body);
1914 return const StatementType();
1915 } 1910 }
1916 1911
1917 visitLabeledStatement(LabeledStatement node) { 1912 visitLabeledStatement(LabeledStatement node) {
1918 return analyze(node.statement); 1913 analyzeNode(node.statement);
1919 } 1914 }
1920 1915
1921 visitLiteralMap(LiteralMap node) { 1916 visitLiteralMap(LiteralMap node) {
1922 InterfaceType mapType = elements.getType(node); 1917 InterfaceType mapType = elements.getType(node);
1923 DartType mapKeyType = firstType(mapType.typeArguments); 1918 DartType mapKeyType = firstType(mapType.typeArguments);
1924 DartType mapValueType = secondType(mapType.typeArguments); 1919 DartType mapValueType = secondType(mapType.typeArguments);
1925 bool isConst = node.isConst; 1920 bool isConst = node.isConst;
1926 for (Link<Node> link = node.entries.nodes; 1921 for (Link<Node> link = node.entries.nodes;
1927 !link.isEmpty; 1922 !link.isEmpty;
1928 link = link.tail) { 1923 link = link.tail) {
(...skipping 29 matching lines...) Expand all
1958 hasDefaultCase = true; 1953 hasDefaultCase = true;
1959 } 1954 }
1960 for (Node labelOrCase in switchCase.labelsAndCases) { 1955 for (Node labelOrCase in switchCase.labelsAndCases) {
1961 CaseMatch caseMatch = labelOrCase.asCaseMatch(); 1956 CaseMatch caseMatch = labelOrCase.asCaseMatch();
1962 if (caseMatch == null) continue; 1957 if (caseMatch == null) continue;
1963 1958
1964 DartType caseType = analyze(caseMatch.expression); 1959 DartType caseType = analyze(caseMatch.expression);
1965 checkAssignable(caseMatch, expressionType, caseType); 1960 checkAssignable(caseMatch, expressionType, caseType);
1966 } 1961 }
1967 1962
1968 analyze(switchCase); 1963 analyzeNode(switchCase);
1969 } 1964 }
1970 1965
1971 if (!hasDefaultCase && expressionType.isEnumType) { 1966 if (!hasDefaultCase && expressionType.isEnumType) {
1972 compiler.enqueuer.resolution.addDeferredAction(executableContext, () { 1967 compiler.enqueuer.resolution.addDeferredAction(executableContext, () {
1973 Map<ConstantValue, FieldElement> enumValues = 1968 Map<ConstantValue, FieldElement> enumValues =
1974 <ConstantValue, FieldElement>{}; 1969 <ConstantValue, FieldElement>{};
1975 List<FieldElement> unreferencedFields = <FieldElement>[]; 1970 List<FieldElement> unreferencedFields = <FieldElement>[];
1976 EnumClassElement enumClass = expressionType.element; 1971 EnumClassElement enumClass = expressionType.element;
1977 enumClass.enumValues.forEach((EnumConstantElement field) { 1972 enumClass.enumValues.forEach((EnumConstantElement field) {
1978 // TODO(johnniwinther): Ensure that the enum constant is computed at 1973 // TODO(johnniwinther): Ensure that the enum constant is computed at
(...skipping 22 matching lines...) Expand all
2001 } 1996 }
2002 unreferencedFields.addAll(enumValues.values); 1997 unreferencedFields.addAll(enumValues.values);
2003 if (!unreferencedFields.isEmpty) { 1998 if (!unreferencedFields.isEmpty) {
2004 reporter.reportWarningMessage(node, MessageKind.MISSING_ENUM_CASES, { 1999 reporter.reportWarningMessage(node, MessageKind.MISSING_ENUM_CASES, {
2005 'enumType': expressionType, 2000 'enumType': expressionType,
2006 'enumValues': unreferencedFields.map((e) => e.name).join(', ') 2001 'enumValues': unreferencedFields.map((e) => e.name).join(', ')
2007 }); 2002 });
2008 } 2003 }
2009 }); 2004 });
2010 } 2005 }
2011
2012 return const StatementType();
2013 } 2006 }
2014 2007
2015 visitSwitchCase(SwitchCase node) { 2008 visitSwitchCase(SwitchCase node) {
2016 return analyze(node.statements); 2009 analyzeNode(node.statements);
2017 } 2010 }
2018 2011
2019 visitTryStatement(TryStatement node) { 2012 visitTryStatement(TryStatement node) {
2020 // TODO(johnniwinther): Use reachability information of try-block, 2013 // TODO(johnniwinther): Use reachability information of try-block,
2021 // catch-blocks and finally-block to compute the whether the try statement 2014 // catch-blocks and finally-block to compute the whether the try statement
2022 // is returning. 2015 // is returning.
2023 analyze(node.tryBlock); 2016 analyzeNode(node.tryBlock);
2024 for (CatchBlock catchBlock in node.catchBlocks) { 2017 for (CatchBlock catchBlock in node.catchBlocks) {
2025 analyze(catchBlock); 2018 analyzeNode(catchBlock);
2026 } 2019 }
2027 analyzeWithDefault(node.finallyBlock, null); 2020 analyzeNode(node.finallyBlock);
2028 return const StatementType();
2029 } 2021 }
2030 2022
2031 visitCatchBlock(CatchBlock node) { 2023 visitCatchBlock(CatchBlock node) {
2032 return analyze(node.block); 2024 analyzeNode(node.block);
2033 } 2025 }
2034 2026
2035 visitTypedef(Typedef node) { 2027 visitTypedef(Typedef node) {
2036 // Do not typecheck [Typedef] nodes. 2028 // Do not typecheck [Typedef] nodes.
2037 } 2029 }
2038 2030
2039 visitNode(Node node) { 2031 visitNode(Node node) {
2040 reporter.internalError(node, 2032 reporter.internalError(node,
2041 'Unexpected node ${node.getObjectDescription()} in the type checker.'); 2033 'Unexpected node ${node.getObjectDescription()} in the type checker.');
2042 } 2034 }
2043 } 2035 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/graph_builder.dart ('k') | tests/compiler/dart2js/type_checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698