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

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1462133005: Downwards inference. This adds support to the resolver for downwards (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments 2 Created 5 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 engine.resolver; 5 library engine.resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import '../task/strong/info.dart' show InferredType, StaticInfo;
10 import '../task/strong/rules.dart' show TypeRules;
9 import 'ast.dart'; 11 import 'ast.dart';
10 import 'constant.dart'; 12 import 'constant.dart';
11 import 'element.dart'; 13 import 'element.dart';
12 import 'element_resolver.dart'; 14 import 'element_resolver.dart';
13 import 'engine.dart'; 15 import 'engine.dart';
14 import 'error.dart'; 16 import 'error.dart';
15 import 'error_verifier.dart'; 17 import 'error_verifier.dart';
16 import 'html.dart' as ht; 18 import 'html.dart' as ht;
17 import 'java_core.dart'; 19 import 'java_core.dart';
18 import 'java_engine.dart'; 20 import 'java_engine.dart';
(...skipping 5729 matching lines...) Expand 10 before | Expand all | Expand 10 after
5748 List<ImportDirective> importList = _libraryMap[libraryElement]; 5750 List<ImportDirective> importList = _libraryMap[libraryElement];
5749 if (importList == null) { 5751 if (importList == null) {
5750 importList = new List<ImportDirective>(); 5752 importList = new List<ImportDirective>();
5751 _libraryMap[libraryElement] = importList; 5753 _libraryMap[libraryElement] = importList;
5752 } 5754 }
5753 importList.add(importDirective); 5755 importList.add(importDirective);
5754 } 5756 }
5755 } 5757 }
5756 5758
5757 /** 5759 /**
5760 * Maintains and manages contextual type information used for
5761 * inferring types.
5762 */
5763 class InferenceContext {
5764 // TODO(leafp): Consider replacing these node properties with a
5765 // hash table help in an instance of this class.
5766 static const String _typeProperty =
5767 'analyzer.src.generated.InferenceContext.contextType';
5768
5769 /**
5770 * The error listener on which to record inference information.
5771 */
5772 final AnalysisErrorListener _errorListener;
5773
5774 /**
5775 * Type provider, needed for type matching.
5776 */
5777 final TypeProvider _typeProvider;
5778
5779 /**
5780 * The type system in use.
5781 */
5782 final TypeSystem _typeSystem;
5783
5784 /**
5785 * The DDC type rules, used to create the inference info nodes.
5786 */
5787 final TypeRules _rules;
5788
5789 /**
5790 * A stack of return types for all of the enclosing
5791 * functions and methods.
5792 */
5793 List<DartType> _returnStack = <DartType>[];
5794
5795 InferenceContext._(
5796 this._errorListener, TypeProvider typeProvider, this._typeSystem)
5797 : _typeProvider = typeProvider,
5798 _rules = new TypeRules(typeProvider);
5799
5800 /**
5801 * Get the return type of the current enclosing function, if any.
5802 */
5803 DartType get returnContext =>
5804 (_returnStack.isNotEmpty) ? _returnStack.last : null;
5805
5806 /**
5807 * Match type [t1] against type [t2] as follows.
5808 * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype
5809 * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>`
5810 * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'`
5811 * to derive a concrete instantation for I of the form `<T0, ..., Tn>`,
5812 * such that `I<T0, .., Tn> <: t2`
5813 */
5814 List<DartType> matchTypes(DartType t1, DartType t2) =>
5815 (t1 is InterfaceType && t2 is InterfaceType) ? _matchTypes(t1, t2) : null;
5816
5817 /**
5818 * Pop a return type off of the return stack.
5819 */
5820 void popReturnContext() {
5821 assert(_returnStack.isNotEmpty);
5822 if (_returnStack.isNotEmpty) {
5823 _returnStack.removeLast();
5824 }
5825 }
5826
5827 /**
5828 * Push a [returnType] onto the return stack.
5829 */
5830 void pushReturnContext(DartType returnType) {
5831 _returnStack.add(returnType);
5832 }
5833
5834 /**
5835 * Place an info node into the error stream indicating that a
5836 * [type] has been inferred as the type of [node].
5837 */
5838 void recordInference(Expression node, DartType type) {
5839 StaticInfo info = InferredType.create(_rules, node, type);
5840 if (info == null) {
5841 return;
5842 }
5843 AnalysisError error = info.toAnalysisError();
5844 _errorListener.onError(error);
5845 }
5846
5847 List<DartType> _matchTypes(InterfaceType t1, InterfaceType t2) {
5848 if (t1 == t2) {
5849 return t2.typeArguments;
5850 }
5851 List<DartType> tArgs1 = t1.typeArguments;
5852 List<DartType> tArgs2 = t2.typeArguments;
5853 // If t1 isn't a raw type, bail out
5854 if (tArgs1 != null && tArgs1.any((t) => !t.isDynamic)) {
5855 return null;
5856 }
5857
5858 // This is our inferred type argument list. We start at all dynamic,
5859 // and fill in with inferred types when we reach a match.
5860 List<DartType> actuals =
5861 new List<DartType>.filled(tArgs1.length, _typeProvider.dynamicType);
5862
5863 // When we find the supertype of t1 with the same
5864 // classname as t2 (see below), we have the following:
5865 // If t1 is an instantiation of a class T1<X0, ..., Xn>
5866 // and t2 is an instantiation of a class T2<Y0, ...., Ym>
5867 // of the form t2 = T2<S0, ..., Sm>
5868 // then we want to choose instantiations for the Xi
5869 // T0, ..., Tn such that T1<T0, ..., Tn> <: t2 .
5870 // To find this, we simply instantate T1 with
5871 // X0, ..., Xn, and then find its superclass
5872 // T2<T0', ..., Tn'>. We then solve the constraint
5873 // set T0' <: S0, ..., Tn' <: Sn for the Xi.
5874 // Currently, we only handle constraints where
5875 // the Ti' is one of the Xi'. If there are multiple
5876 // constraints on some Xi, we choose the lower of the
5877 // two (if it exists).
5878 bool permute(List<DartType> permutedArgs) {
5879 if (permutedArgs == null) {
5880 return false;
5881 }
5882 List<TypeParameterElement> ps = t1.typeParameters;
5883 List<DartType> ts = ps.map((p) => p.type).toList();
5884 for (int i = 0; i < permutedArgs.length; i++) {
5885 DartType tVar = permutedArgs[i];
5886 DartType tActual = tArgs2[i];
5887 int index = ts.indexOf(tVar);
5888 if (index >= 0 && _typeSystem.isSubtypeOf(tActual, actuals[index])) {
5889 actuals[index] = tActual;
5890 }
5891 }
5892 return actuals.any((x) => !x.isDynamic);
5893 }
5894
5895 // Look for the first supertype of t1 with the same class name as t2.
5896 bool match(InterfaceType t1, Set<Element> visited) {
5897 if (t1.element == t2.element) {
5898 return permute(t1.typeArguments);
5899 }
5900
5901 if (t1 == _typeProvider.objectType) {
5902 return false;
5903 }
5904
5905 Element element = t1.element;
5906 if (visited == null) {
5907 visited = new HashSet<Element>();
5908 }
5909 if (element == null || !visited.add(element)) {
5910 return false;
5911 }
5912 try {
5913 if (match(t1.superclass, visited)) {
5914 return true;
5915 }
5916
5917 for (final parent in t1.mixins) {
5918 if (match(parent, visited)) {
5919 return true;
5920 }
5921 }
5922
5923 for (final parent in t1.interfaces) {
5924 if (match(parent, visited)) {
5925 return true;
5926 }
5927 }
5928 } finally {
5929 visited.remove(element);
5930 }
5931 return false;
5932 }
5933
5934 // We have that t1 = T1<dynamic, ..., dynamic>.
5935 // To match t1 against t2, we use the uninstantiated version
5936 // of t1, essentially treating it as an instantiation with
5937 // fresh variables, and solve for the variables.
5938 // t1.element.type will be of the form T1<X0, ..., Xn>
5939 if (!match(t1.element.type, null)) {
5940 return null;
5941 }
5942 DartType newT1 = t1.element.type.substitute4(actuals);
5943 // If we found a solution, return it.
5944 if (_typeSystem.isSubtypeOf(newT1, t2)) {
5945 return actuals;
5946 }
5947 return null;
5948 }
5949
5950 /**
5951 * Clear the type information assocated with [node].
5952 */
5953 static void clearType(AstNode node) {
5954 node?.setProperty(_typeProperty, null);
5955 }
5956
5957 /**
5958 * Look for contextual type information attached to [node]. Returns
5959 * the type if found, otherwise null.
5960 */
5961 static DartType getType(AstNode node) => node?.getProperty(_typeProperty);
5962
5963 /**
5964 * Attach contextual type information [type] to [node] for use during
5965 * inference.
5966 */
5967 static void setType(AstNode node, DartType type) {
5968 node?.setProperty(_typeProperty, type);
5969 }
5970
5971 /**
5972 * Attach contextual type information [type] to [node] for use during
5973 * inference.
5974 */
5975 static void setTypeFromNode(AstNode innerNode, AstNode outerNode) {
5976 setType(innerNode, getType(outerNode));
5977 }
5978 }
5979
5980 /**
5758 * Instances of the class `InheritanceManager` manage the knowledge of where cla ss members 5981 * Instances of the class `InheritanceManager` manage the knowledge of where cla ss members
5759 * (methods, getters & setters) are inherited from. 5982 * (methods, getters & setters) are inherited from.
5760 */ 5983 */
5761 class InheritanceManager { 5984 class InheritanceManager {
5762 /** 5985 /**
5763 * The [LibraryElement] that is managed by this manager. 5986 * The [LibraryElement] that is managed by this manager.
5764 */ 5987 */
5765 LibraryElement _library; 5988 LibraryElement _library;
5766 5989
5767 /** 5990 /**
(...skipping 4610 matching lines...) Expand 10 before | Expand all | Expand 10 after
10378 * The object used to resolve the element associated with the current node. 10601 * The object used to resolve the element associated with the current node.
10379 */ 10602 */
10380 ElementResolver elementResolver; 10603 ElementResolver elementResolver;
10381 10604
10382 /** 10605 /**
10383 * The object used to compute the type associated with the current node. 10606 * The object used to compute the type associated with the current node.
10384 */ 10607 */
10385 StaticTypeAnalyzer typeAnalyzer; 10608 StaticTypeAnalyzer typeAnalyzer;
10386 10609
10387 /* 10610 /*
10388 * The type system in use during resolution. 10611 * The type system in use during resolution.
10389 */ 10612 */
10390 TypeSystem typeSystem; 10613 TypeSystem typeSystem;
10391 10614
10392 /** 10615 /**
10393 * The class element representing the class containing the current node, 10616 * The class element representing the class containing the current node,
10394 * or `null` if the current node is not contained in a class. 10617 * or `null` if the current node is not contained in a class.
10395 */ 10618 */
10396 ClassElement enclosingClass = null; 10619 ClassElement enclosingClass = null;
10397 10620
10398 /** 10621 /**
10399 * The class declaration representing the class containing the current node, o r `null` if 10622 * The class declaration representing the class containing the current node, o r `null` if
(...skipping 12 matching lines...) Expand all
10412 * current node is not contained in a function. 10635 * current node is not contained in a function.
10413 */ 10636 */
10414 ExecutableElement _enclosingFunction = null; 10637 ExecutableElement _enclosingFunction = null;
10415 10638
10416 /** 10639 /**
10417 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that 10640 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that
10418 * cannot be resolved where we visited it, because it should be resolved in th e scope of the body. 10641 * cannot be resolved where we visited it, because it should be resolved in th e scope of the body.
10419 */ 10642 */
10420 Comment _commentBeforeFunction = null; 10643 Comment _commentBeforeFunction = null;
10421 10644
10645 InferenceContext inferenceContext = null;
10646
10422 /** 10647 /**
10423 * The object keeping track of which elements have had their types overridden. 10648 * The object keeping track of which elements have had their types overridden.
10424 */ 10649 */
10425 TypeOverrideManager _overrideManager = new TypeOverrideManager(); 10650 TypeOverrideManager _overrideManager = new TypeOverrideManager();
10426 10651
10427 /** 10652 /**
10428 * The object keeping track of which elements have had their types promoted. 10653 * The object keeping track of which elements have had their types promoted.
10429 */ 10654 */
10430 TypePromotionManager _promoteManager = new TypePromotionManager(); 10655 TypePromotionManager _promoteManager = new TypePromotionManager();
10431 10656
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
10463 StaticTypeAnalyzerFactory typeAnalyzerFactory}) 10688 StaticTypeAnalyzerFactory typeAnalyzerFactory})
10464 : super(definingLibrary, source, typeProvider, errorListener, 10689 : super(definingLibrary, source, typeProvider, errorListener,
10465 nameScope: nameScope) { 10690 nameScope: nameScope) {
10466 if (inheritanceManager == null) { 10691 if (inheritanceManager == null) {
10467 this._inheritanceManager = new InheritanceManager(definingLibrary); 10692 this._inheritanceManager = new InheritanceManager(definingLibrary);
10468 } else { 10693 } else {
10469 this._inheritanceManager = inheritanceManager; 10694 this._inheritanceManager = inheritanceManager;
10470 } 10695 }
10471 this.elementResolver = new ElementResolver(this); 10696 this.elementResolver = new ElementResolver(this);
10472 this.typeSystem = definingLibrary.context.typeSystem; 10697 this.typeSystem = definingLibrary.context.typeSystem;
10698 this.inferenceContext =
10699 new InferenceContext._(errorListener, typeProvider, typeSystem);
10473 if (typeAnalyzerFactory == null) { 10700 if (typeAnalyzerFactory == null) {
10474 this.typeAnalyzer = new StaticTypeAnalyzer(this); 10701 this.typeAnalyzer = new StaticTypeAnalyzer(this);
10475 } else { 10702 } else {
10476 this.typeAnalyzer = typeAnalyzerFactory(this); 10703 this.typeAnalyzer = typeAnalyzerFactory(this);
10477 } 10704 }
10478 } 10705 }
10479 10706
10480 /** 10707 /**
10481 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 10708 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
10482 * 10709 *
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
10735 expression.propagatedType = type; 10962 expression.propagatedType = type;
10736 } 10963 }
10737 10964
10738 @override 10965 @override
10739 Object visitAnnotation(Annotation node) { 10966 Object visitAnnotation(Annotation node) {
10740 AstNode parent = node.parent; 10967 AstNode parent = node.parent;
10741 if (identical(parent, _enclosingClassDeclaration) || 10968 if (identical(parent, _enclosingClassDeclaration) ||
10742 identical(parent, _enclosingFunctionTypeAlias)) { 10969 identical(parent, _enclosingFunctionTypeAlias)) {
10743 return null; 10970 return null;
10744 } 10971 }
10745 return super.visitAnnotation(node); 10972 safelyVisit(node.name);
10973 safelyVisit(node.constructorName);
10974 Element element = node.element;
10975 if (element is ExecutableElement) {
10976 InferenceContext.setType(node.arguments, element.type);
10977 }
10978 safelyVisit(node.arguments);
10979 node.accept(elementResolver);
10980 node.accept(typeAnalyzer);
10981 return null;
10982 }
10983
10984 @override
10985 Object visitArgumentList(ArgumentList node) {
10986 DartType callerType = InferenceContext.getType(node);
10987 if (callerType is FunctionType) {
10988 Map<String, DartType> namedParameterTypes =
10989 callerType.namedParameterTypes;
10990 List<DartType> normalParameterTypes = callerType.normalParameterTypes;
10991 List<DartType> optionalParameterTypes = callerType.optionalParameterTypes;
10992 int normalCount = normalParameterTypes.length;
10993 int optionalCount = optionalParameterTypes.length;
10994
10995 NodeList<Expression> arguments = node.arguments;
10996 Iterable<Expression> positional =
10997 arguments.takeWhile((l) => l is! NamedExpression);
10998 Iterable<Expression> required = positional.take(normalCount);
10999 Iterable<Expression> optional =
11000 positional.skip(normalCount).take(optionalCount);
11001 Iterable<Expression> named =
11002 arguments.skipWhile((l) => l is! NamedExpression);
11003
11004 //TODO(leafp): Consider using the parameter elements here instead.
11005 //TODO(leafp): Make sure that the parameter elements are getting
11006 // setup correctly with inference.
11007 int index = 0;
11008 for (Expression argument in required) {
11009 InferenceContext.setType(argument, normalParameterTypes[index++]);
11010 }
11011 index = 0;
11012 for (Expression argument in optional) {
11013 InferenceContext.setType(argument, optionalParameterTypes[index++]);
11014 }
11015
11016 for (Expression argument in named) {
11017 if (argument is NamedExpression) {
11018 DartType type = namedParameterTypes[argument.name.label.name];
11019 if (type != null) {
11020 InferenceContext.setType(argument, type);
11021 }
11022 }
11023 }
11024 }
11025 return super.visitArgumentList(node);
10746 } 11026 }
10747 11027
10748 @override 11028 @override
10749 Object visitAsExpression(AsExpression node) { 11029 Object visitAsExpression(AsExpression node) {
11030 InferenceContext.setType(node.expression, node.type.type);
10750 super.visitAsExpression(node); 11031 super.visitAsExpression(node);
10751 // Since an as-statement doesn't actually change the type, we don't 11032 // Since an as-statement doesn't actually change the type, we don't
10752 // let it affect the propagated type when it would result in a loss 11033 // let it affect the propagated type when it would result in a loss
10753 // of precision. 11034 // of precision.
10754 overrideExpression(node.expression, node.type.type, false, false); 11035 overrideExpression(node.expression, node.type.type, false, false);
10755 return null; 11036 return null;
10756 } 11037 }
10757 11038
10758 @override 11039 @override
10759 Object visitAssertStatement(AssertStatement node) { 11040 Object visitAssertStatement(AssertStatement node) {
10760 super.visitAssertStatement(node); 11041 super.visitAssertStatement(node);
10761 _propagateTrueState(node.condition); 11042 _propagateTrueState(node.condition);
10762 return null; 11043 return null;
10763 } 11044 }
10764 11045
10765 @override 11046 @override
11047 Object visitAssignmentExpression(AssignmentExpression node) {
11048 safelyVisit(node.leftHandSide);
11049 sc.TokenType operator = node.operator.type;
11050 if (operator == sc.TokenType.EQ ||
11051 operator == sc.TokenType.QUESTION_QUESTION_EQ) {
11052 InferenceContext.setType(
11053 node.rightHandSide, node.leftHandSide.staticType);
11054 }
11055 safelyVisit(node.rightHandSide);
11056 node.accept(elementResolver);
11057 node.accept(typeAnalyzer);
11058 return null;
11059 }
11060
11061 @override
11062 Object visitAwaitExpression(AwaitExpression node) {
11063 //TODO(leafp): Handle the implicit union type here
11064 DartType contextType = InferenceContext.getType(node);
11065 if (contextType != null) {
11066 InterfaceType futureT =
11067 typeProvider.futureType.substitute4([contextType]);
11068 InferenceContext.setType(node.expression, futureT);
11069 }
11070 return super.visitAwaitExpression(node);
11071 }
11072
11073 @override
10766 Object visitBinaryExpression(BinaryExpression node) { 11074 Object visitBinaryExpression(BinaryExpression node) {
10767 sc.TokenType operatorType = node.operator.type; 11075 sc.TokenType operatorType = node.operator.type;
10768 Expression leftOperand = node.leftOperand; 11076 Expression leftOperand = node.leftOperand;
10769 Expression rightOperand = node.rightOperand; 11077 Expression rightOperand = node.rightOperand;
10770 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) { 11078 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
10771 safelyVisit(leftOperand); 11079 safelyVisit(leftOperand);
10772 if (rightOperand != null) { 11080 if (rightOperand != null) {
10773 _overrideManager.enterScope(); 11081 _overrideManager.enterScope();
10774 try { 11082 try {
10775 _promoteManager.enterScope(); 11083 _promoteManager.enterScope();
(...skipping 19 matching lines...) Expand all
10795 if (rightOperand != null) { 11103 if (rightOperand != null) {
10796 _overrideManager.enterScope(); 11104 _overrideManager.enterScope();
10797 try { 11105 try {
10798 _propagateFalseState(leftOperand); 11106 _propagateFalseState(leftOperand);
10799 rightOperand.accept(this); 11107 rightOperand.accept(this);
10800 } finally { 11108 } finally {
10801 _overrideManager.exitScope(); 11109 _overrideManager.exitScope();
10802 } 11110 }
10803 } 11111 }
10804 } else { 11112 } else {
11113 // TODO(leafp): Do downwards inference using the declared type
11114 // of the binary operator.
10805 safelyVisit(leftOperand); 11115 safelyVisit(leftOperand);
10806 safelyVisit(rightOperand); 11116 safelyVisit(rightOperand);
10807 } 11117 }
10808 node.accept(elementResolver); 11118 node.accept(elementResolver);
10809 node.accept(typeAnalyzer); 11119 node.accept(typeAnalyzer);
10810 return null; 11120 return null;
10811 } 11121 }
10812 11122
10813 @override 11123 @override
10814 Object visitBlockFunctionBody(BlockFunctionBody node) { 11124 Object visitBlockFunctionBody(BlockFunctionBody node) {
10815 safelyVisit(_commentBeforeFunction); 11125 safelyVisit(_commentBeforeFunction);
10816 _overrideManager.enterScope(); 11126 _overrideManager.enterScope();
10817 try { 11127 try {
11128 inferenceContext.pushReturnContext(InferenceContext.getType(node));
10818 super.visitBlockFunctionBody(node); 11129 super.visitBlockFunctionBody(node);
10819 } finally { 11130 } finally {
10820 _overrideManager.exitScope(); 11131 _overrideManager.exitScope();
11132 inferenceContext.popReturnContext();
10821 } 11133 }
10822 return null; 11134 return null;
10823 } 11135 }
10824 11136
10825 @override 11137 @override
10826 Object visitBreakStatement(BreakStatement node) { 11138 Object visitBreakStatement(BreakStatement node) {
10827 // 11139 //
10828 // We do not visit the label because it needs to be visited in the context 11140 // We do not visit the label because it needs to be visited in the context
10829 // of the statement. 11141 // of the statement.
10830 // 11142 //
10831 node.accept(elementResolver); 11143 node.accept(elementResolver);
10832 node.accept(typeAnalyzer); 11144 node.accept(typeAnalyzer);
10833 return null; 11145 return null;
10834 } 11146 }
10835 11147
10836 @override 11148 @override
11149 Object visitCascadeExpression(CascadeExpression node) {
11150 InferenceContext.setTypeFromNode(node.target, node);
11151 return super.visitCascadeExpression(node);
11152 }
11153
11154 @override
10837 Object visitClassDeclaration(ClassDeclaration node) { 11155 Object visitClassDeclaration(ClassDeclaration node) {
10838 // 11156 //
10839 // Resolve the metadata in the library scope. 11157 // Resolve the metadata in the library scope.
10840 // 11158 //
10841 if (node.metadata != null) { 11159 if (node.metadata != null) {
10842 node.metadata.accept(this); 11160 node.metadata.accept(this);
10843 } 11161 }
10844 _enclosingClassDeclaration = node; 11162 _enclosingClassDeclaration = node;
10845 // 11163 //
10846 // Continue the class resolution. 11164 // Continue the class resolution.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
10959 try { 11277 try {
10960 _promoteManager.enterScope(); 11278 _promoteManager.enterScope();
10961 try { 11279 try {
10962 _propagateTrueState(condition); 11280 _propagateTrueState(condition);
10963 // Type promotion. 11281 // Type promotion.
10964 _promoteTypes(condition); 11282 _promoteTypes(condition);
10965 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); 11283 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
10966 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( 11284 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
10967 thenExpression); 11285 thenExpression);
10968 // Visit "then" expression. 11286 // Visit "then" expression.
11287 InferenceContext.setTypeFromNode(thenExpression, node);
10969 thenExpression.accept(this); 11288 thenExpression.accept(this);
10970 } finally { 11289 } finally {
10971 _promoteManager.exitScope(); 11290 _promoteManager.exitScope();
10972 } 11291 }
10973 } finally { 11292 } finally {
10974 _overrideManager.exitScope(); 11293 _overrideManager.exitScope();
10975 } 11294 }
10976 } 11295 }
10977 Expression elseExpression = node.elseExpression; 11296 Expression elseExpression = node.elseExpression;
10978 if (elseExpression != null) { 11297 if (elseExpression != null) {
10979 _overrideManager.enterScope(); 11298 _overrideManager.enterScope();
10980 try { 11299 try {
10981 _propagateFalseState(condition); 11300 _propagateFalseState(condition);
11301 InferenceContext.setTypeFromNode(elseExpression, node);
10982 elseExpression.accept(this); 11302 elseExpression.accept(this);
10983 } finally { 11303 } finally {
10984 _overrideManager.exitScope(); 11304 _overrideManager.exitScope();
10985 } 11305 }
10986 } 11306 }
10987 node.accept(elementResolver); 11307 node.accept(elementResolver);
10988 node.accept(typeAnalyzer); 11308 node.accept(typeAnalyzer);
10989 bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression); 11309 bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression);
10990 bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression); 11310 bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression);
10991 if (elseIsAbrupt && !thenIsAbrupt) { 11311 if (elseIsAbrupt && !thenIsAbrupt) {
10992 _propagateTrueState(condition); 11312 _propagateTrueState(condition);
10993 _propagateState(thenExpression); 11313 _propagateState(thenExpression);
10994 } else if (thenIsAbrupt && !elseIsAbrupt) { 11314 } else if (thenIsAbrupt && !elseIsAbrupt) {
10995 _propagateFalseState(condition); 11315 _propagateFalseState(condition);
10996 _propagateState(elseExpression); 11316 _propagateState(elseExpression);
10997 } 11317 }
10998 return null; 11318 return null;
10999 } 11319 }
11000 11320
11001 @override 11321 @override
11002 Object visitConstructorDeclaration(ConstructorDeclaration node) { 11322 Object visitConstructorDeclaration(ConstructorDeclaration node) {
11003 ExecutableElement outerFunction = _enclosingFunction; 11323 ExecutableElement outerFunction = _enclosingFunction;
11004 try { 11324 try {
11005 _enclosingFunction = node.element; 11325 _enclosingFunction = node.element;
11326 FunctionType type = _enclosingFunction.type;
11327 InferenceContext.setType(node.body, type.returnType);
11006 super.visitConstructorDeclaration(node); 11328 super.visitConstructorDeclaration(node);
11007 } finally { 11329 } finally {
11008 _enclosingFunction = outerFunction; 11330 _enclosingFunction = outerFunction;
11009 } 11331 }
11010 ConstructorElementImpl constructor = node.element; 11332 ConstructorElementImpl constructor = node.element;
11011 constructor.constantInitializers = 11333 constructor.constantInitializers =
11012 new ConstantAstCloner().cloneNodeList(node.initializers); 11334 new ConstantAstCloner().cloneNodeList(node.initializers);
11013 return null; 11335 return null;
11014 } 11336 }
11015 11337
11016 @override 11338 @override
11017 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 11339 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
11018 // 11340 //
11019 // We visit the expression, but do not visit the field name because it needs 11341 // We visit the expression, but do not visit the field name because it needs
11020 // to be visited in the context of the constructor field initializer node. 11342 // to be visited in the context of the constructor field initializer node.
11021 // 11343 //
11344 FieldElement fieldElement = enclosingClass.getField(node.fieldName.name);
11345 InferenceContext.setType(node.expression, fieldElement?.type);
11022 safelyVisit(node.expression); 11346 safelyVisit(node.expression);
11023 node.accept(elementResolver); 11347 node.accept(elementResolver);
11024 node.accept(typeAnalyzer); 11348 node.accept(typeAnalyzer);
11025 return null; 11349 return null;
11026 } 11350 }
11027 11351
11028 @override 11352 @override
11029 Object visitConstructorName(ConstructorName node) { 11353 Object visitConstructorName(ConstructorName node) {
11030 // 11354 //
11031 // We do not visit either the type name, because it won't be visited anyway, 11355 // We do not visit either the type name, because it won't be visited anyway,
(...skipping 11 matching lines...) Expand all
11043 // We do not visit the label because it needs to be visited in the context 11367 // We do not visit the label because it needs to be visited in the context
11044 // of the statement. 11368 // of the statement.
11045 // 11369 //
11046 node.accept(elementResolver); 11370 node.accept(elementResolver);
11047 node.accept(typeAnalyzer); 11371 node.accept(typeAnalyzer);
11048 return null; 11372 return null;
11049 } 11373 }
11050 11374
11051 @override 11375 @override
11052 Object visitDefaultFormalParameter(DefaultFormalParameter node) { 11376 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
11377 InferenceContext.setType(node.defaultValue, node.parameter.element?.type);
11053 super.visitDefaultFormalParameter(node); 11378 super.visitDefaultFormalParameter(node);
11054 ParameterElement element = node.element; 11379 ParameterElement element = node.element;
11055 if (element.initializer != null && node.defaultValue != null) { 11380 if (element.initializer != null && node.defaultValue != null) {
11056 (element.initializer as FunctionElementImpl).returnType = 11381 (element.initializer as FunctionElementImpl).returnType =
11057 node.defaultValue.staticType; 11382 node.defaultValue.staticType;
11058 } 11383 }
11059 FormalParameterList parent = node.parent; 11384 FormalParameterList parent = node.parent;
11060 AstNode grandparent = parent.parent; 11385 AstNode grandparent = parent.parent;
11061 if (grandparent is ConstructorDeclaration && 11386 if (grandparent is ConstructorDeclaration &&
11062 grandparent.constKeyword != null) { 11387 grandparent.constKeyword != null) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
11121 } 11446 }
11122 11447
11123 @override 11448 @override
11124 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { 11449 Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
11125 safelyVisit(_commentBeforeFunction); 11450 safelyVisit(_commentBeforeFunction);
11126 if (resolveOnlyCommentInFunctionBody) { 11451 if (resolveOnlyCommentInFunctionBody) {
11127 return null; 11452 return null;
11128 } 11453 }
11129 _overrideManager.enterScope(); 11454 _overrideManager.enterScope();
11130 try { 11455 try {
11456 InferenceContext.setTypeFromNode(node.expression, node);
11131 super.visitExpressionFunctionBody(node); 11457 super.visitExpressionFunctionBody(node);
11132 } finally { 11458 } finally {
11133 _overrideManager.exitScope(); 11459 _overrideManager.exitScope();
11134 } 11460 }
11135 return null; 11461 return null;
11136 } 11462 }
11137 11463
11138 @override 11464 @override
11139 Object visitFieldDeclaration(FieldDeclaration node) { 11465 Object visitFieldDeclaration(FieldDeclaration node) {
11140 _overrideManager.enterScope(); 11466 _overrideManager.enterScope();
(...skipping 19 matching lines...) Expand all
11160 return null; 11486 return null;
11161 } 11487 }
11162 11488
11163 @override 11489 @override
11164 void visitForEachStatementInScope(ForEachStatement node) { 11490 void visitForEachStatementInScope(ForEachStatement node) {
11165 // 11491 //
11166 // We visit the iterator before the loop variable because the loop variable 11492 // We visit the iterator before the loop variable because the loop variable
11167 // cannot be in scope while visiting the iterator. 11493 // cannot be in scope while visiting the iterator.
11168 // 11494 //
11169 Expression iterable = node.iterable; 11495 Expression iterable = node.iterable;
11170 safelyVisit(iterable);
11171 DeclaredIdentifier loopVariable = node.loopVariable; 11496 DeclaredIdentifier loopVariable = node.loopVariable;
11172 SimpleIdentifier identifier = node.identifier; 11497 SimpleIdentifier identifier = node.identifier;
11498 if (loopVariable?.type?.type != null) {
11499 InterfaceType targetType = (node.awaitKeyword == null)
11500 ? typeProvider.iterableType
11501 : typeProvider.streamType;
11502 InferenceContext.setType(
11503 iterable, targetType.substitute4([loopVariable.type.type]));
11504 }
11505 safelyVisit(iterable);
11173 safelyVisit(loopVariable); 11506 safelyVisit(loopVariable);
11174 safelyVisit(identifier); 11507 safelyVisit(identifier);
11175 Statement body = node.body; 11508 Statement body = node.body;
11176 if (body != null) { 11509 if (body != null) {
11177 _overrideManager.enterScope(); 11510 _overrideManager.enterScope();
11178 try { 11511 try {
11179 if (loopVariable != null && iterable != null) { 11512 if (loopVariable != null && iterable != null) {
11180 LocalVariableElement loopElement = loopVariable.element; 11513 LocalVariableElement loopElement = loopVariable.element;
11181 if (loopElement != null) { 11514 if (loopElement != null) {
11182 DartType propagatedType = null; 11515 DartType propagatedType = null;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
11235 // TODO(brianwilkerson) If the loop can only be exited because the condition 11568 // TODO(brianwilkerson) If the loop can only be exited because the condition
11236 // is false, then propagateFalseState(condition); 11569 // is false, then propagateFalseState(condition);
11237 } 11570 }
11238 11571
11239 @override 11572 @override
11240 Object visitFunctionDeclaration(FunctionDeclaration node) { 11573 Object visitFunctionDeclaration(FunctionDeclaration node) {
11241 ExecutableElement outerFunction = _enclosingFunction; 11574 ExecutableElement outerFunction = _enclosingFunction;
11242 try { 11575 try {
11243 SimpleIdentifier functionName = node.name; 11576 SimpleIdentifier functionName = node.name;
11244 _enclosingFunction = functionName.staticElement as ExecutableElement; 11577 _enclosingFunction = functionName.staticElement as ExecutableElement;
11578 InferenceContext.setType(
11579 node.functionExpression, _enclosingFunction.type);
11245 super.visitFunctionDeclaration(node); 11580 super.visitFunctionDeclaration(node);
11246 } finally { 11581 } finally {
11247 _enclosingFunction = outerFunction; 11582 _enclosingFunction = outerFunction;
11248 } 11583 }
11249 return null; 11584 return null;
11250 } 11585 }
11251 11586
11252 @override 11587 @override
11253 Object visitFunctionExpression(FunctionExpression node) { 11588 Object visitFunctionExpression(FunctionExpression node) {
11254 ExecutableElement outerFunction = _enclosingFunction; 11589 ExecutableElement outerFunction = _enclosingFunction;
11255 try { 11590 try {
11256 _enclosingFunction = node.element; 11591 _enclosingFunction = node.element;
11257 _overrideManager.enterScope(); 11592 _overrideManager.enterScope();
11258 try { 11593 try {
11594 DartType functionType = InferenceContext.getType(node);
11595 if (functionType is FunctionType) {
11596 _inferFormalParameterList(node.parameters, functionType);
11597 InferenceContext.setType(node.body, functionType.returnType);
11598 }
11259 super.visitFunctionExpression(node); 11599 super.visitFunctionExpression(node);
11260 } finally { 11600 } finally {
11261 _overrideManager.exitScope(); 11601 _overrideManager.exitScope();
11262 } 11602 }
11263 } finally { 11603 } finally {
11264 _enclosingFunction = outerFunction; 11604 _enclosingFunction = outerFunction;
11265 } 11605 }
11266 return null; 11606 return null;
11267 } 11607 }
11268 11608
11269 @override 11609 @override
11270 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { 11610 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
11271 safelyVisit(node.function); 11611 safelyVisit(node.function);
11272 node.accept(elementResolver); 11612 node.accept(elementResolver);
11273 _inferFunctionExpressionsParametersTypes(node.argumentList); 11613 _inferFunctionExpressionsParametersTypes(node.argumentList);
11614 InferenceContext.setType(node.argumentList, node.function.staticType);
11274 safelyVisit(node.argumentList); 11615 safelyVisit(node.argumentList);
11275 node.accept(typeAnalyzer); 11616 node.accept(typeAnalyzer);
11276 return null; 11617 return null;
11277 } 11618 }
11278 11619
11279 @override 11620 @override
11280 Object visitFunctionTypeAlias(FunctionTypeAlias node) { 11621 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
11281 // Resolve the metadata in the library scope. 11622 // Resolve the metadata in the library scope.
11282 if (node.metadata != null) { 11623 if (node.metadata != null) {
11283 node.metadata.accept(this); 11624 node.metadata.accept(this);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
11351 List<Map<VariableElement, DartType>> perBranchOverrides = 11692 List<Map<VariableElement, DartType>> perBranchOverrides =
11352 new List<Map<VariableElement, DartType>>(); 11693 new List<Map<VariableElement, DartType>>();
11353 perBranchOverrides.add(thenOverrides); 11694 perBranchOverrides.add(thenOverrides);
11354 perBranchOverrides.add(elseOverrides); 11695 perBranchOverrides.add(elseOverrides);
11355 _overrideManager.mergeOverrides(perBranchOverrides); 11696 _overrideManager.mergeOverrides(perBranchOverrides);
11356 } 11697 }
11357 return null; 11698 return null;
11358 } 11699 }
11359 11700
11360 @override 11701 @override
11702 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
11703 DartType contextType = InferenceContext.getType(node);
11704 if (contextType is InterfaceType &&
11705 contextType.typeArguments != null &&
11706 contextType.typeArguments.length > 0) {
11707 TypeName classTypeName = node.constructorName.type;
11708 if (classTypeName.typeArguments == null) {
11709 List<DartType> targs =
11710 inferenceContext.matchTypes(classTypeName.type, contextType);
11711 if (targs != null && targs.any((t) => !t.isDynamic)) {
11712 ClassElement classElement = classTypeName.type.element;
11713 InterfaceType rawType = classElement.type;
11714 InterfaceType fullType =
11715 rawType.substitute2(targs, rawType.typeArguments);
11716 // The element resolver uses the type on the constructor name, so
11717 // infer it first
11718 typeAnalyzer.inferConstructorName(node.constructorName, fullType);
11719 safelyVisit(node.constructorName);
11720 ConstructorElement invokedConstructor =
11721 node.constructorName.staticElement;
11722 FunctionType rawConstructorType = invokedConstructor.type;
11723 FunctionType constructorType = rawConstructorType.substitute2(
11724 targs, rawConstructorType.typeArguments);
11725 InferenceContext.setType(node.argumentList, constructorType);
11726 safelyVisit(node.argumentList);
11727 InferenceContext.setType(node, fullType);
11728 node.accept(elementResolver);
11729 node.accept(typeAnalyzer);
11730 return null;
11731 }
11732 } else {
11733 InferenceContext.clearType(node);
11734 }
11735 }
11736 super.visitInstanceCreationExpression(node);
11737 return null;
11738 }
11739
11740 @override
11361 Object visitLabel(Label node) => null; 11741 Object visitLabel(Label node) => null;
11362 11742
11363 @override 11743 @override
11364 Object visitLibraryIdentifier(LibraryIdentifier node) => null; 11744 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
11365 11745
11366 @override 11746 @override
11747 Object visitListLiteral(ListLiteral node) {
11748 DartType contextType = InferenceContext.getType(node);
11749 if (node.typeArguments == null && contextType is InterfaceType) {
11750 InterfaceType listD =
11751 typeProvider.listType.substitute4([typeProvider.dynamicType]);
11752 List<DartType> targs = inferenceContext.matchTypes(listD, contextType);
11753 if (targs != null &&
11754 targs.length == 1 &&
11755 targs.any((t) => !t.isDynamic)) {
11756 DartType eType = targs[0];
11757 InterfaceType listT = typeProvider.listType.substitute4([eType]);
11758 for (Expression child in node.elements) {
11759 InferenceContext.setType(child, eType);
11760 }
11761 InferenceContext.setType(node, listT);
11762 } else {
11763 InferenceContext.clearType(node);
11764 }
11765 }
11766 super.visitListLiteral(node);
11767 return null;
11768 }
11769
11770 @override
11771 Object visitMapLiteral(MapLiteral node) {
11772 DartType contextType = InferenceContext.getType(node);
11773 if (node.typeArguments == null && contextType is InterfaceType) {
11774 InterfaceType mapD = typeProvider.mapType
11775 .substitute4([typeProvider.dynamicType, typeProvider.dynamicType]);
11776 List<DartType> targs = inferenceContext.matchTypes(mapD, contextType);
11777 if (targs != null &&
11778 targs.length == 2 &&
11779 targs.any((t) => !t.isDynamic)) {
11780 DartType kType = targs[0];
11781 DartType vType = targs[1];
11782 InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]);
11783 for (MapLiteralEntry entry in node.entries) {
11784 InferenceContext.setType(entry.key, kType);
11785 InferenceContext.setType(entry.value, vType);
11786 }
11787 InferenceContext.setType(node, mapT);
11788 } else {
11789 InferenceContext.clearType(node);
11790 }
11791 }
11792 super.visitMapLiteral(node);
11793 return null;
11794 }
11795
11796 @override
11367 Object visitMethodDeclaration(MethodDeclaration node) { 11797 Object visitMethodDeclaration(MethodDeclaration node) {
11368 ExecutableElement outerFunction = _enclosingFunction; 11798 ExecutableElement outerFunction = _enclosingFunction;
11369 try { 11799 try {
11370 _enclosingFunction = node.element; 11800 _enclosingFunction = node.element;
11801 InferenceContext.setType(node.body, node.element.type?.returnType);
11371 super.visitMethodDeclaration(node); 11802 super.visitMethodDeclaration(node);
11372 } finally { 11803 } finally {
11373 _enclosingFunction = outerFunction; 11804 _enclosingFunction = outerFunction;
11374 } 11805 }
11375 return null; 11806 return null;
11376 } 11807 }
11377 11808
11378 @override 11809 @override
11379 Object visitMethodInvocation(MethodInvocation node) { 11810 Object visitMethodInvocation(MethodInvocation node) {
11380 // 11811 //
11381 // We visit the target and argument list, but do not visit the method name 11812 // We visit the target and argument list, but do not visit the method name
11382 // because it needs to be visited in the context of the invocation. 11813 // because it needs to be visited in the context of the invocation.
11383 // 11814 //
11384 safelyVisit(node.target); 11815 safelyVisit(node.target);
11385 node.accept(elementResolver); 11816 node.accept(elementResolver);
11386 _inferFunctionExpressionsParametersTypes(node.argumentList); 11817 _inferFunctionExpressionsParametersTypes(node.argumentList);
11818 Element methodElement = node.methodName.staticElement;
11819 if (methodElement is ExecutableElement) {
11820 InferenceContext.setType(node.argumentList, methodElement.type);
11821 }
11387 safelyVisit(node.argumentList); 11822 safelyVisit(node.argumentList);
11388 node.accept(typeAnalyzer); 11823 node.accept(typeAnalyzer);
11389 return null; 11824 return null;
11390 } 11825 }
11391 11826
11392 @override 11827 @override
11828 Object visitNamedExpression(NamedExpression node) {
11829 InferenceContext.setType(node.expression, InferenceContext.getType(node));
11830 return super.visitNamedExpression(node);
11831 }
11832
11833 @override
11393 Object visitNode(AstNode node) { 11834 Object visitNode(AstNode node) {
11394 node.visitChildren(this); 11835 node.visitChildren(this);
11395 node.accept(elementResolver); 11836 node.accept(elementResolver);
11396 node.accept(typeAnalyzer); 11837 node.accept(typeAnalyzer);
11397 return null; 11838 return null;
11398 } 11839 }
11399 11840
11400 @override 11841 @override
11842 Object visitParenthesizedExpression(ParenthesizedExpression node) {
11843 InferenceContext.setType(node.expression, InferenceContext.getType(node));
11844 return super.visitParenthesizedExpression(node);
11845 }
11846
11847 @override
11401 Object visitPrefixedIdentifier(PrefixedIdentifier node) { 11848 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
11402 // 11849 //
11403 // We visit the prefix, but do not visit the identifier because it needs to 11850 // We visit the prefix, but do not visit the identifier because it needs to
11404 // be visited in the context of the prefix. 11851 // be visited in the context of the prefix.
11405 // 11852 //
11406 safelyVisit(node.prefix); 11853 safelyVisit(node.prefix);
11407 node.accept(elementResolver); 11854 node.accept(elementResolver);
11408 node.accept(typeAnalyzer); 11855 node.accept(typeAnalyzer);
11409 return null; 11856 return null;
11410 } 11857 }
(...skipping 11 matching lines...) Expand all
11422 } 11869 }
11423 11870
11424 @override 11871 @override
11425 Object visitRedirectingConstructorInvocation( 11872 Object visitRedirectingConstructorInvocation(
11426 RedirectingConstructorInvocation node) { 11873 RedirectingConstructorInvocation node) {
11427 // 11874 //
11428 // We visit the argument list, but do not visit the optional identifier 11875 // We visit the argument list, but do not visit the optional identifier
11429 // because it needs to be visited in the context of the constructor 11876 // because it needs to be visited in the context of the constructor
11430 // invocation. 11877 // invocation.
11431 // 11878 //
11879 InferenceContext.setType(node.argumentList, node.staticElement?.type);
11432 safelyVisit(node.argumentList); 11880 safelyVisit(node.argumentList);
11433 node.accept(elementResolver); 11881 node.accept(elementResolver);
11434 node.accept(typeAnalyzer); 11882 node.accept(typeAnalyzer);
11435 return null; 11883 return null;
11436 } 11884 }
11437 11885
11438 @override 11886 @override
11887 Object visitReturnStatement(ReturnStatement node) {
11888 InferenceContext.setType(node.expression, inferenceContext.returnContext);
11889 return super.visitReturnStatement(node);
11890 }
11891
11892 @override
11439 Object visitShowCombinator(ShowCombinator node) => null; 11893 Object visitShowCombinator(ShowCombinator node) => null;
11440 11894
11441 @override 11895 @override
11442 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { 11896 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
11443 // 11897 //
11444 // We visit the argument list, but do not visit the optional identifier 11898 // We visit the argument list, but do not visit the optional identifier
11445 // because it needs to be visited in the context of the constructor 11899 // because it needs to be visited in the context of the constructor
11446 // invocation. 11900 // invocation.
11447 // 11901 //
11902 InferenceContext.setType(node.argumentList, node.staticElement?.type);
11448 safelyVisit(node.argumentList); 11903 safelyVisit(node.argumentList);
11449 node.accept(elementResolver); 11904 node.accept(elementResolver);
11450 node.accept(typeAnalyzer); 11905 node.accept(typeAnalyzer);
11451 return null; 11906 return null;
11452 } 11907 }
11453 11908
11454 @override 11909 @override
11455 Object visitSwitchCase(SwitchCase node) { 11910 Object visitSwitchCase(SwitchCase node) {
11456 _overrideManager.enterScope(); 11911 _overrideManager.enterScope();
11457 try { 11912 try {
(...skipping 27 matching lines...) Expand all
11485 _overrideManager.applyOverrides(overrides); 11940 _overrideManager.applyOverrides(overrides);
11486 } 11941 }
11487 return null; 11942 return null;
11488 } 11943 }
11489 11944
11490 @override 11945 @override
11491 Object visitTypeName(TypeName node) => null; 11946 Object visitTypeName(TypeName node) => null;
11492 11947
11493 @override 11948 @override
11494 Object visitVariableDeclaration(VariableDeclaration node) { 11949 Object visitVariableDeclaration(VariableDeclaration node) {
11950 InferenceContext.setType(node.initializer, InferenceContext.getType(node));
11495 super.visitVariableDeclaration(node); 11951 super.visitVariableDeclaration(node);
11496 VariableElement element = node.element; 11952 VariableElement element = node.element;
11497 if (element.initializer != null && node.initializer != null) { 11953 if (element.initializer != null && node.initializer != null) {
11498 (element.initializer as FunctionElementImpl).returnType = 11954 (element.initializer as FunctionElementImpl).returnType =
11499 node.initializer.staticType; 11955 node.initializer.staticType;
11500 } 11956 }
11501 // Note: in addition to cloning the initializers for const variables, we 11957 // Note: in addition to cloning the initializers for const variables, we
11502 // have to clone the initializers for non-static final fields (because if 11958 // have to clone the initializers for non-static final fields (because if
11503 // they occur in a class with a const constructor, they will be needed to 11959 // they occur in a class with a const constructor, they will be needed to
11504 // evaluate the const constructor). 11960 // evaluate the const constructor).
11505 if ((element.isConst || 11961 if ((element.isConst ||
11506 (element is FieldElement && 11962 (element is FieldElement &&
11507 element.isFinal && 11963 element.isFinal &&
11508 !element.isStatic)) && 11964 !element.isStatic)) &&
11509 node.initializer != null) { 11965 node.initializer != null) {
11510 (element as ConstVariableElement).constantInitializer = 11966 (element as ConstVariableElement).constantInitializer =
11511 new ConstantAstCloner().cloneNode(node.initializer); 11967 new ConstantAstCloner().cloneNode(node.initializer);
11512 } 11968 }
11513 return null; 11969 return null;
11514 } 11970 }
11515 11971
11972 @override visitVariableDeclarationList(VariableDeclarationList node) {
11973 for (VariableDeclaration decl in node.variables) {
11974 InferenceContext.setType(decl, node.type?.type);
11975 }
11976 super.visitVariableDeclarationList(node);
11977 }
11978
11516 @override 11979 @override
11517 Object visitWhileStatement(WhileStatement node) { 11980 Object visitWhileStatement(WhileStatement node) {
11518 // Note: since we don't call the base class, we have to maintain 11981 // Note: since we don't call the base class, we have to maintain
11519 // _implicitLabelScope ourselves. 11982 // _implicitLabelScope ourselves.
11520 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; 11983 ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
11521 try { 11984 try {
11522 _implicitLabelScope = _implicitLabelScope.nest(node); 11985 _implicitLabelScope = _implicitLabelScope.nest(node);
11523 Expression condition = node.condition; 11986 Expression condition = node.condition;
11524 safelyVisit(condition); 11987 safelyVisit(condition);
11525 Statement body = node.body; 11988 Statement body = node.body;
11526 if (body != null) { 11989 if (body != null) {
11527 _overrideManager.enterScope(); 11990 _overrideManager.enterScope();
11528 try { 11991 try {
11529 _propagateTrueState(condition); 11992 _propagateTrueState(condition);
11530 visitStatementInScope(body); 11993 visitStatementInScope(body);
11531 } finally { 11994 } finally {
11532 _overrideManager.exitScope(); 11995 _overrideManager.exitScope();
11533 } 11996 }
11534 } 11997 }
11535 } finally { 11998 } finally {
11536 _implicitLabelScope = outerImplicitScope; 11999 _implicitLabelScope = outerImplicitScope;
11537 } 12000 }
11538 // TODO(brianwilkerson) If the loop can only be exited because the condition 12001 // TODO(brianwilkerson) If the loop can only be exited because the condition
11539 // is false, then propagateFalseState(condition); 12002 // is false, then propagateFalseState(condition);
11540 node.accept(elementResolver); 12003 node.accept(elementResolver);
11541 node.accept(typeAnalyzer); 12004 node.accept(typeAnalyzer);
11542 return null; 12005 return null;
11543 } 12006 }
11544 12007
12008 @override
12009 Object visitYieldStatement(YieldStatement node) {
12010 DartType returnType = inferenceContext.returnContext;
12011 if (returnType != null && _enclosingFunction != null) {
12012 // If we're not in a generator ([a]sync*, then we shouldn't have a yield.
12013 // so don't infer
12014 if (_enclosingFunction.isGenerator) {
12015 // If this is a yield*, then we just propagate the return type downwards
12016 DartType type = returnType;
12017 // If this just a yield, then we need to get the element type
12018 if (node.star == null) {
12019 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T>
12020 InterfaceType wrapperD = _enclosingFunction.isSynchronous
12021 ? typeProvider.iterableDynamicType
12022 : typeProvider.streamDynamicType;
12023 // Match the types to instantiate the type arguments if possible
12024 List<DartType> targs =
12025 inferenceContext.matchTypes(wrapperD, returnType);
12026 type = (targs?.length == 1) ? targs[0] : null;
12027 }
12028 InferenceContext.setType(node.expression, type);
12029 }
12030 }
12031 return super.visitYieldStatement(node);
12032 }
12033
11545 /** 12034 /**
11546 * Checks each promoted variable in the current scope for compliance with the following 12035 * Checks each promoted variable in the current scope for compliance with the following
11547 * specification statement: 12036 * specification statement:
11548 * 12037 *
11549 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t hen the variable 12038 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t hen the variable
11550 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. 12039 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>.
11551 */ 12040 */
11552 void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( 12041 void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
11553 AstNode target) { 12042 AstNode target) {
11554 for (Element element in _promoteManager.promotedElements) { 12043 for (Element element in _promoteManager.promotedElements) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
11629 List<ParameterElement> onDataParameters = onDataType.parameters; 12118 List<ParameterElement> onDataParameters = onDataType.parameters;
11630 if (onDataParameters == null || onDataParameters.isEmpty) { 12119 if (onDataParameters == null || onDataParameters.isEmpty) {
11631 return null; 12120 return null;
11632 } 12121 }
11633 return onDataParameters[0].type; 12122 return onDataParameters[0].type;
11634 } 12123 }
11635 } 12124 }
11636 return null; 12125 return null;
11637 } 12126 }
11638 12127
12128 void _inferFormalParameterList(FormalParameterList node, DartType type) {
12129 if (typeAnalyzer.inferFormalParameterList(node, type)) {
12130 // TODO(leafp): This gets dropped on the floor if we're in the field
12131 // inference task. We should probably keep these infos.
12132 inferenceContext.recordInference(node.parent, type);
12133 }
12134 }
12135
11639 /** 12136 /**
11640 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its 12137 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its
11641 * required type is [FunctionType], then infer parameters types from [Function Type]. 12138 * required type is [FunctionType], then infer parameters types from [Function Type].
11642 */ 12139 */
11643 void _inferFunctionExpressionParametersTypes( 12140 void _inferFunctionExpressionParametersTypes(
11644 Expression mayBeClosure, DartType mayByFunctionType) { 12141 Expression mayBeClosure, DartType mayByFunctionType) {
11645 // prepare closure 12142 // prepare closure
11646 if (mayBeClosure is! FunctionExpression) { 12143 if (mayBeClosure is! FunctionExpression) {
11647 return; 12144 return;
11648 } 12145 }
(...skipping 3913 matching lines...) Expand 10 before | Expand all | Expand 10 after
15562 nonFields.add(node); 16059 nonFields.add(node);
15563 return null; 16060 return null;
15564 } 16061 }
15565 16062
15566 @override 16063 @override
15567 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); 16064 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this);
15568 16065
15569 @override 16066 @override
15570 Object visitWithClause(WithClause node) => null; 16067 Object visitWithClause(WithClause node) => null;
15571 } 16068 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698