Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 5728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5747 LibraryElement libraryElement, ImportDirective importDirective) { | 5749 LibraryElement libraryElement, ImportDirective importDirective) { |
| 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 |
| 5759 /** Maintains and manages contextual type information used for | |
|
Brian Wilkerson
2015/11/21 16:12:22
Not asking for a change, but I'm not a fan of the
Jennifer Messerly
2015/11/23 22:11:57
Yeah same here. I've been trying to follow:
/**
Leaf
2015/12/01 21:49:11
Done.
Brian Wilkerson
2015/12/01 22:31:09
Personally, I find the "///" style hard to read, s
Bob Nystrom
2015/12/01 23:33:27
I'll point out two things:
1. The style guide req
Leaf
2015/12/01 23:39:24
Per point 2: that's my fault (caught in the review
| |
| 5760 * inferring types. | |
| 5761 */ | |
| 5762 class InferenceContext { | |
|
Jennifer Messerly
2015/11/23 22:11:57
"Context" as a class suffix often just means "here
Leaf
2015/12/01 21:49:11
Acknowledged.
| |
| 5763 /** The key by which we hang information off of ast nodes. | |
| 5764 */ | |
| 5765 static const String _propertyName = | |
|
Jennifer Messerly
2015/11/23 22:11:57
might be worth giving this a more descriptive name
Leaf
2015/12/01 21:49:11
Done.
| |
| 5766 'analyzer.src.generated.InferenceContext.contextType'; | |
| 5767 | |
| 5768 /** The error listener on which to record inference information. | |
| 5769 */ | |
| 5770 final AnalysisErrorListener _errorListener; | |
| 5771 | |
| 5772 /** Type provider, needed for type matching. | |
| 5773 */ | |
| 5774 final TypeProvider _typeProvider; | |
| 5775 | |
| 5776 /** The type system in use. | |
| 5777 */ | |
| 5778 final TypeSystem _typeSystem; | |
| 5779 | |
| 5780 /** The DDC type rules, used to create the inference info nodes. | |
| 5781 */ | |
| 5782 final TypeRules _rules; | |
|
Jennifer Messerly
2015/11/23 22:11:57
Question: are we still on track to remove this obj
Leaf
2015/11/24 19:32:12
Yes. It's here only to produce the info nodes tha
| |
| 5783 | |
| 5784 /** A stack of return types for all of the enclosing | |
| 5785 * functions and methods. | |
| 5786 */ | |
| 5787 List<DartType> _returnStack = <DartType>[]; | |
| 5788 | |
| 5789 InferenceContext( | |
|
Jennifer Messerly
2015/11/23 22:11:58
BTW, if either the type or constructor can be made
Leaf
2015/11/24 19:32:11
The type has to be public since it's accessed by t
Jennifer Messerly
2015/11/24 20:10:57
InferenceContext._(...)
Leaf
2015/12/01 21:49:11
Done.
| |
| 5790 this._errorListener, TypeProvider typeProvider, this._typeSystem) | |
| 5791 : this._typeProvider = typeProvider, | |
|
Jennifer Messerly
2015/11/23 22:11:57
nit: "this." is not necessary here
Leaf
2015/12/01 21:49:10
Done.
| |
| 5792 this._rules = new TypeRules(typeProvider); | |
| 5793 | |
| 5794 /** Get the return type of the current enclusing function, if any. | |
|
Brian Wilkerson
2015/11/21 16:12:22
"enclusing" --> "enclosing"
Leaf
2015/12/01 21:49:11
Done.
| |
| 5795 */ | |
| 5796 DartType get returnContext => | |
| 5797 (_returnStack.isNotEmpty) ? _returnStack.last : null; | |
| 5798 | |
| 5799 /** If t1 = I<dynamic, ..., dynamic>, then look for a supertype | |
|
Jennifer Messerly
2015/11/23 22:11:57
BTW: you probably want to put backticks around gen
Leaf
2015/12/01 21:49:11
Done.
| |
| 5800 * of t1 of the form K<S0, ..., Sm> where t2 = K<S0', ..., Sm'> | |
|
Brian Wilkerson
2015/11/21 16:12:22
What is 't2'?
Jennifer Messerly
2015/11/23 22:11:57
looks like it's the second argument to matchTypes
Leaf
2015/12/01 21:49:11
Added a line to the comments to make this clearer.
| |
| 5801 * If the supertype exists, use the constraints S0 <: S0', ... Sm <: Sm' | |
| 5802 * to derive a concrete instantation for I of the form <T0, ..., Tn>, | |
| 5803 * such that I<T0, .., Tn> <: t2 | |
| 5804 */ | |
| 5805 List<DartType> matchTypes(DartType t1, DartType t2) => | |
| 5806 (t1 is InterfaceType && t2 is InterfaceType) ? _matchTypes(t1, t2) : null; | |
| 5807 | |
| 5808 /** Pop a return type off of the return stack. | |
| 5809 */ | |
| 5810 void popReturnContext() { | |
| 5811 if (_returnStack.isNotEmpty) { | |
|
Brian Wilkerson
2015/11/21 16:12:22
Add "assert(_returnStack.isNotEmpty);" before the
Leaf
2015/12/01 21:49:11
Done.
| |
| 5812 _returnStack.removeLast(); | |
| 5813 } | |
| 5814 } | |
| 5815 | |
| 5816 /** Push a [returnType] onto the return stack. | |
| 5817 */ | |
| 5818 void pushReturnContext(DartType returnType) { | |
| 5819 _returnStack.add(returnType); | |
| 5820 } | |
| 5821 | |
| 5822 /** Place an info node into the error stream indicating that a | |
| 5823 * [type] has been inferred as the type of [node]. | |
| 5824 */ | |
| 5825 void recordInference(Expression node, DartType type) { | |
| 5826 StaticInfo info = InferredType.create(_rules, node, type); | |
| 5827 if (info == null) return; | |
|
Brian Wilkerson
2015/11/21 16:12:22
Stylistic nit (for here and elsewhere): we always
Leaf
2015/11/24 19:32:12
Sorry - pulled over from DDC code and I missed the
Leaf
2015/12/01 21:49:11
Done.
| |
| 5828 var error = info.toAnalysisError(); | |
| 5829 _errorListener.onError(error); | |
| 5830 } | |
| 5831 | |
| 5832 List<DartType> _matchTypes(InterfaceType t1, InterfaceType t2) { | |
| 5833 if (t1 == t2) { | |
| 5834 return t2.typeArguments; | |
| 5835 } | |
| 5836 List<DartType> tArgs1 = t1.typeArguments; | |
| 5837 List<DartType> tArgs2 = t2.typeArguments; | |
| 5838 // If t1 isn't a raw type, bail out | |
| 5839 if (tArgs1 != null && tArgs1.any((t) => !t.isDynamic)) { | |
| 5840 return null; | |
| 5841 } | |
| 5842 | |
| 5843 // This is our inferred type argument list. We start at all dynamic, | |
| 5844 // and fill in with inferred types when we reach a match. | |
| 5845 List<DartType> actuals = | |
| 5846 new List<DartType>.filled(tArgs1.length, _typeProvider.dynamicType); | |
| 5847 | |
| 5848 // When we find the supertype of t1 with the same | |
| 5849 // classname as t2 (see below), we have the following: | |
| 5850 // If t1 is an instantiation of a class T1<X0, ..., Xn> | |
| 5851 // and t2 is an instantiation of a class T2<Y0, ...., Ym> | |
| 5852 // of the form t2 = T2<S0, ..., Sm> | |
| 5853 // then we want to choose instantiations for the Xi | |
| 5854 // T0, ..., Tn such that T1<T0, ..., Tn> <: t2 . | |
| 5855 // To find this, we simply instantate T1 with | |
| 5856 // X0, ..., Xn, and then find its superclass | |
| 5857 // T2<T0', ..., Tn'>. We then solve the constraint | |
| 5858 // set T0' <: S0, ..., Tn' <: Sn for the Xi. | |
| 5859 // Currently, we only handle constraints where | |
| 5860 // the Ti' is one of the Xi'. If there are multiple | |
| 5861 // constraints on some Xi, we choose the lower of the | |
| 5862 // two (if it exists). | |
| 5863 bool permute(List<DartType> permutedArgs) { | |
| 5864 if (permutedArgs == null) { | |
| 5865 return false; | |
| 5866 } | |
| 5867 List<TypeParameterElement> ps = t1.typeParameters; | |
| 5868 List<DartType> ts = ps.map((p) => p.type).toList(); | |
| 5869 for (int i = 0; i < permutedArgs.length; i++) { | |
| 5870 DartType tVar = permutedArgs[i]; | |
| 5871 DartType tActual = tArgs2[i]; | |
| 5872 int index = ts.indexOf(tVar); | |
| 5873 if (index >= 0 && _typeSystem.isSubtypeOf(tActual, actuals[index])) { | |
| 5874 actuals[index] = tActual; | |
| 5875 } | |
| 5876 } | |
| 5877 return actuals.any((x) => !x.isDynamic); | |
| 5878 } | |
| 5879 | |
| 5880 // Look for the first supertype of t1 with the same class name as t2. | |
| 5881 bool match(InterfaceType t1) { | |
|
Brian Wilkerson
2015/11/21 16:12:22
This method will result in an infinite loop if the
Leaf
2015/12/01 21:49:11
Done.
| |
| 5882 if (t1.element == t2.element) { | |
| 5883 return permute(t1.typeArguments); | |
| 5884 } | |
| 5885 | |
| 5886 if (t1 == _typeProvider.objectType) { | |
| 5887 return false; | |
| 5888 } | |
| 5889 | |
| 5890 if (match(t1.superclass)) { | |
| 5891 return true; | |
| 5892 } | |
| 5893 | |
| 5894 for (final parent in t1.interfaces) { | |
| 5895 if (match(parent)) { | |
| 5896 return true; | |
| 5897 } | |
| 5898 } | |
| 5899 | |
| 5900 for (final parent in t1.mixins) { | |
|
Brian Wilkerson
2015/11/21 16:12:22
Interesting that we do mixins after interfaces. I
Jennifer Messerly
2015/11/23 22:11:58
Yeah. I would normally think of mixins as coming b
Leaf
2015/11/24 19:32:11
I need to sit down and work through the details of
| |
| 5901 if (match(parent)) { | |
| 5902 return true; | |
| 5903 } | |
| 5904 } | |
| 5905 return false; | |
| 5906 } | |
| 5907 | |
| 5908 // We have that t1 = T1<dynamic, ..., dynamic>. | |
| 5909 // To match t1 against t2, we use the uninstantiated version | |
| 5910 // of t1, essentially treating it as an instantiation with | |
| 5911 // fresh variables, and solve for the variables. | |
| 5912 // t1.element.type will be of the form T1<X0, ..., Xn> | |
| 5913 if (!match(t1.element.type)) return null; | |
| 5914 DartType newT1 = t1.element.type.substitute4(actuals); | |
| 5915 // If we found a solution, return it. | |
| 5916 if (_typeSystem.isSubtypeOf(newT1, t2)) return actuals; | |
| 5917 return null; | |
| 5918 } | |
| 5919 | |
| 5920 /** Attach contextual type information [type] to [node] for use during | |
| 5921 * inference. | |
| 5922 */ | |
| 5923 static void annotateNode(AstNode node, DartType type) { | |
|
Jennifer Messerly
2015/11/23 22:11:58
(note: the following may be obsolete in light of m
Leaf
2015/12/01 21:49:10
Done.
| |
| 5924 node?.setProperty(_propertyName, type); | |
|
Jennifer Messerly
2015/11/23 22:11:57
hmmmm. Thinking on this more (having seen the use
Leaf
2015/11/24 19:32:12
Yeah, I think this would be fine. I initially did
Brian Wilkerson
2015/11/24 21:17:57
I don't have a problem with either approach.
The
Leaf
2015/12/01 21:49:11
I'm leaving it as it is for now, but added a todo
| |
| 5925 return; | |
|
Jennifer Messerly
2015/11/23 22:11:57
nit: return not needed here
Leaf
2015/12/01 21:49:10
The visitor methods seem to always explicitly retu
| |
| 5926 } | |
| 5927 | |
| 5928 /** Clear the type information assocated with [node]. | |
| 5929 */ | |
| 5930 static void clear(AstNode node) { | |
| 5931 node?.setProperty(_propertyName, null); | |
| 5932 return; | |
| 5933 } | |
| 5934 | |
| 5935 // If t1 = I<dynamic, ..., dynamic>, then look for a supertype | |
|
Jennifer Messerly
2015/11/23 22:11:57
Is this supposed to be here? Consider folding it i
Leaf
2015/12/01 21:49:10
Done.
| |
| 5936 // of t1 of the form K<S0, ..., Sm> where t2 = K<S0', ..., Sm'> | |
| 5937 // If the supertype exists, use the constraints S0 <: S0', ... Sm <: Sm' | |
| 5938 // to derive a concrete instantation for I of the form <T0, ..., Tn>, | |
| 5939 // such that I<T0, .., Tn> <: t2 | |
| 5940 /** Look for contextual type information attached to [node]. Returns | |
| 5941 * the type if found, otherwise null. | |
| 5942 */ | |
| 5943 static DartType get(AstNode node) => node?.getProperty(_propertyName); | |
| 5944 } | |
| 5945 | |
| 5757 /** | 5946 /** |
| 5758 * Instances of the class `InheritanceManager` manage the knowledge of where cla ss members | 5947 * Instances of the class `InheritanceManager` manage the knowledge of where cla ss members |
| 5759 * (methods, getters & setters) are inherited from. | 5948 * (methods, getters & setters) are inherited from. |
| 5760 */ | 5949 */ |
| 5761 class InheritanceManager { | 5950 class InheritanceManager { |
| 5762 /** | 5951 /** |
| 5763 * The [LibraryElement] that is managed by this manager. | 5952 * The [LibraryElement] that is managed by this manager. |
| 5764 */ | 5953 */ |
| 5765 LibraryElement _library; | 5954 LibraryElement _library; |
| 5766 | 5955 |
| (...skipping 4598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10365 * The object used to resolve the element associated with the current node. | 10554 * The object used to resolve the element associated with the current node. |
| 10366 */ | 10555 */ |
| 10367 ElementResolver elementResolver; | 10556 ElementResolver elementResolver; |
| 10368 | 10557 |
| 10369 /** | 10558 /** |
| 10370 * The object used to compute the type associated with the current node. | 10559 * The object used to compute the type associated with the current node. |
| 10371 */ | 10560 */ |
| 10372 StaticTypeAnalyzer typeAnalyzer; | 10561 StaticTypeAnalyzer typeAnalyzer; |
| 10373 | 10562 |
| 10374 /* | 10563 /* |
| 10375 * The type system in use during resolution. | 10564 * The type system in use during resolution. |
| 10376 */ | 10565 */ |
| 10377 TypeSystem typeSystem; | 10566 TypeSystem typeSystem; |
| 10378 | 10567 |
| 10379 /** | 10568 /** |
| 10380 * The class element representing the class containing the current node, | 10569 * The class element representing the class containing the current node, |
| 10381 * or `null` if the current node is not contained in a class. | 10570 * or `null` if the current node is not contained in a class. |
| 10382 */ | 10571 */ |
| 10383 ClassElement enclosingClass = null; | 10572 ClassElement enclosingClass = null; |
| 10384 | 10573 |
| 10385 /** | 10574 /** |
| 10386 * The class declaration representing the class containing the current node, o r `null` if | 10575 * The class declaration representing the class containing the current node, o r `null` if |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 10399 * current node is not contained in a function. | 10588 * current node is not contained in a function. |
| 10400 */ | 10589 */ |
| 10401 ExecutableElement _enclosingFunction = null; | 10590 ExecutableElement _enclosingFunction = null; |
| 10402 | 10591 |
| 10403 /** | 10592 /** |
| 10404 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that | 10593 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that |
| 10405 * cannot be resolved where we visited it, because it should be resolved in th e scope of the body. | 10594 * cannot be resolved where we visited it, because it should be resolved in th e scope of the body. |
| 10406 */ | 10595 */ |
| 10407 Comment _commentBeforeFunction = null; | 10596 Comment _commentBeforeFunction = null; |
| 10408 | 10597 |
| 10598 InferenceContext inferenceContext = null; | |
|
Jennifer Messerly
2015/11/23 22:11:58
hmmm, I guess this is for consistency, but `= null
Leaf
2015/12/01 21:49:11
Acknowledged.
| |
| 10599 | |
| 10409 /** | 10600 /** |
| 10410 * The object keeping track of which elements have had their types overridden. | 10601 * The object keeping track of which elements have had their types overridden. |
| 10411 */ | 10602 */ |
| 10412 TypeOverrideManager _overrideManager = new TypeOverrideManager(); | 10603 TypeOverrideManager _overrideManager = new TypeOverrideManager(); |
| 10413 | 10604 |
| 10414 /** | 10605 /** |
| 10415 * The object keeping track of which elements have had their types promoted. | 10606 * The object keeping track of which elements have had their types promoted. |
| 10416 */ | 10607 */ |
| 10417 TypePromotionManager _promoteManager = new TypePromotionManager(); | 10608 TypePromotionManager _promoteManager = new TypePromotionManager(); |
| 10418 | 10609 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10450 StaticTypeAnalyzerFactory typeAnalyzerFactory}) | 10641 StaticTypeAnalyzerFactory typeAnalyzerFactory}) |
| 10451 : super(definingLibrary, source, typeProvider, errorListener, | 10642 : super(definingLibrary, source, typeProvider, errorListener, |
| 10452 nameScope: nameScope) { | 10643 nameScope: nameScope) { |
| 10453 if (inheritanceManager == null) { | 10644 if (inheritanceManager == null) { |
| 10454 this._inheritanceManager = new InheritanceManager(definingLibrary); | 10645 this._inheritanceManager = new InheritanceManager(definingLibrary); |
| 10455 } else { | 10646 } else { |
| 10456 this._inheritanceManager = inheritanceManager; | 10647 this._inheritanceManager = inheritanceManager; |
| 10457 } | 10648 } |
| 10458 this.elementResolver = new ElementResolver(this); | 10649 this.elementResolver = new ElementResolver(this); |
| 10459 this.typeSystem = definingLibrary.context.typeSystem; | 10650 this.typeSystem = definingLibrary.context.typeSystem; |
| 10651 this.inferenceContext = | |
| 10652 new InferenceContext(errorListener, typeProvider, typeSystem); | |
| 10460 if (typeAnalyzerFactory == null) { | 10653 if (typeAnalyzerFactory == null) { |
| 10461 this.typeAnalyzer = new StaticTypeAnalyzer(this); | 10654 this.typeAnalyzer = new StaticTypeAnalyzer(this); |
| 10462 } else { | 10655 } else { |
| 10463 this.typeAnalyzer = typeAnalyzerFactory(this); | 10656 this.typeAnalyzer = typeAnalyzerFactory(this); |
| 10464 } | 10657 } |
| 10465 } | 10658 } |
| 10466 | 10659 |
| 10467 /** | 10660 /** |
| 10468 * Initialize a newly created visitor to resolve the nodes in a compilation un it. | 10661 * Initialize a newly created visitor to resolve the nodes in a compilation un it. |
| 10469 * | 10662 * |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10722 expression.propagatedType = type; | 10915 expression.propagatedType = type; |
| 10723 } | 10916 } |
| 10724 | 10917 |
| 10725 @override | 10918 @override |
| 10726 Object visitAnnotation(Annotation node) { | 10919 Object visitAnnotation(Annotation node) { |
| 10727 AstNode parent = node.parent; | 10920 AstNode parent = node.parent; |
| 10728 if (identical(parent, _enclosingClassDeclaration) || | 10921 if (identical(parent, _enclosingClassDeclaration) || |
| 10729 identical(parent, _enclosingFunctionTypeAlias)) { | 10922 identical(parent, _enclosingFunctionTypeAlias)) { |
| 10730 return null; | 10923 return null; |
| 10731 } | 10924 } |
| 10732 return super.visitAnnotation(node); | 10925 safelyVisit(node.name); |
| 10926 safelyVisit(node.constructorName); | |
| 10927 Element element = node.element; | |
| 10928 if (element is ExecutableElement) { | |
| 10929 InferenceContext.annotateNode(node.arguments, element.type); | |
| 10930 } | |
| 10931 safelyVisit(node.arguments); | |
| 10932 node.accept(elementResolver); | |
| 10933 node.accept(typeAnalyzer); | |
| 10934 return null; | |
| 10935 } | |
| 10936 | |
| 10937 @override | |
| 10938 Object visitArgumentList(ArgumentList node) { | |
| 10939 DartType callerType = InferenceContext.get(node); | |
| 10940 if (callerType is FunctionType) { | |
| 10941 Map<String, DartType> namedParameterTypes = | |
| 10942 callerType.namedParameterTypes; | |
| 10943 List<DartType> normalParameterTypes = callerType.normalParameterTypes; | |
| 10944 List<DartType> optionalParameterTypes = callerType.optionalParameterTypes; | |
| 10945 int normalCount = normalParameterTypes.length; | |
| 10946 int optionalCount = optionalParameterTypes.length; | |
| 10947 int namedCount = namedParameterTypes.length; | |
| 10948 | |
| 10949 NodeList<Expression> arguments = node.arguments; | |
| 10950 Iterable<Expression> positional = | |
| 10951 arguments.takeWhile((l) => l is! NamedExpression); | |
| 10952 Iterable<Expression> required = positional.take(normalCount); | |
| 10953 Iterable<Expression> optional = | |
| 10954 positional.skip(normalCount).take(optionalCount); | |
| 10955 Iterable<Expression> named = | |
| 10956 arguments.skipWhile((l) => l is! NamedExpression); | |
| 10957 | |
| 10958 int index = 0; | |
|
Jennifer Messerly
2015/11/23 22:11:57
trivial: I'd probably just write this as a C-style
Leaf
2015/11/24 19:32:12
The for loop version above will throw an out of bo
Jennifer Messerly
2015/11/24 20:10:58
Ah, in that case, probably best to leave it as is!
| |
| 10959 for (Expression argument in required) { | |
| 10960 InferenceContext.annotateNode(argument, normalParameterTypes[index++]); | |
|
Jennifer Messerly
2015/11/23 22:11:58
you might be able to avoid some of the above logic
Leaf
2015/12/01 21:49:11
Maybe? I'd have to think through the various impl
| |
| 10961 } | |
| 10962 index = 0; | |
| 10963 for (Expression argument in optional) { | |
| 10964 InferenceContext.annotateNode( | |
| 10965 argument, optionalParameterTypes[index++]); | |
| 10966 } | |
| 10967 | |
| 10968 for (Expression argument in named) { | |
| 10969 if (argument is NamedExpression && | |
| 10970 namedParameterTypes.containsKey(argument.name.label.name)) { | |
|
Jennifer Messerly
2015/11/23 22:11:57
not that it matters, but I'd be tempted to rewrite
Leaf
2015/12/01 21:49:11
Done.
| |
| 10971 InferenceContext.annotateNode( | |
| 10972 argument, namedParameterTypes[argument.name.label.name]); | |
| 10973 } | |
| 10974 } | |
| 10975 } | |
| 10976 super.visitArgumentList(node); | |
|
Brian Wilkerson
2015/11/21 16:12:22
Missing return
Leaf
2015/12/01 21:49:10
Done.
| |
| 10733 } | 10977 } |
| 10734 | 10978 |
| 10735 @override | 10979 @override |
| 10736 Object visitAsExpression(AsExpression node) { | 10980 Object visitAsExpression(AsExpression node) { |
| 10981 InferenceContext.annotateNode(node.expression, node.type.type); | |
| 10737 super.visitAsExpression(node); | 10982 super.visitAsExpression(node); |
| 10738 // Since an as-statement doesn't actually change the type, we don't | 10983 // Since an as-statement doesn't actually change the type, we don't |
| 10739 // let it affect the propagated type when it would result in a loss | 10984 // let it affect the propagated type when it would result in a loss |
| 10740 // of precision. | 10985 // of precision. |
| 10741 overrideExpression(node.expression, node.type.type, false, false); | 10986 overrideExpression(node.expression, node.type.type, false, false); |
| 10742 return null; | 10987 return null; |
| 10743 } | 10988 } |
| 10744 | 10989 |
| 10745 @override | 10990 @override |
| 10746 Object visitAssertStatement(AssertStatement node) { | 10991 Object visitAssertStatement(AssertStatement node) { |
| 10747 super.visitAssertStatement(node); | 10992 super.visitAssertStatement(node); |
| 10748 _propagateTrueState(node.condition); | 10993 _propagateTrueState(node.condition); |
| 10749 return null; | 10994 return null; |
| 10750 } | 10995 } |
| 10751 | 10996 |
| 10752 @override | 10997 @override |
| 10998 Object visitAssignmentExpression(AssignmentExpression node) { | |
| 10999 safelyVisit(node.leftHandSide); | |
| 11000 sc.TokenType operator = node.operator.type; | |
| 11001 if (operator == sc.TokenType.EQ || | |
| 11002 operator == sc.TokenType.QUESTION_QUESTION_EQ) { | |
| 11003 InferenceContext.annotateNode( | |
| 11004 node.rightHandSide, node.leftHandSide.staticType); | |
| 11005 } | |
| 11006 safelyVisit(node.rightHandSide); | |
| 11007 node.accept(elementResolver); | |
| 11008 node.accept(typeAnalyzer); | |
| 11009 return null; | |
| 11010 } | |
| 11011 | |
| 11012 @override | |
| 11013 Object visitAwaitExpression(AwaitExpression node) { | |
| 11014 //TODO(leafp): Handle the implicit union type here | |
| 11015 DartType contextType = InferenceContext.get(node); | |
| 11016 if (contextType != null) { | |
| 11017 InterfaceType futureT = | |
| 11018 typeProvider.futureType.substitute4([contextType]); | |
| 11019 InferenceContext.annotateNode(node.expression, futureT); | |
| 11020 } | |
| 11021 super.visitAwaitExpression(node); | |
| 11022 return null; | |
|
Brian Wilkerson
2015/11/21 16:12:22
Or "return super.visitAwaitExpression(node);"
Leaf
2015/12/01 21:49:10
Done.
| |
| 11023 } | |
| 11024 | |
| 11025 @override | |
| 10753 Object visitBinaryExpression(BinaryExpression node) { | 11026 Object visitBinaryExpression(BinaryExpression node) { |
| 10754 sc.TokenType operatorType = node.operator.type; | 11027 sc.TokenType operatorType = node.operator.type; |
| 10755 Expression leftOperand = node.leftOperand; | 11028 Expression leftOperand = node.leftOperand; |
| 10756 Expression rightOperand = node.rightOperand; | 11029 Expression rightOperand = node.rightOperand; |
| 10757 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) { | 11030 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) { |
| 10758 safelyVisit(leftOperand); | 11031 safelyVisit(leftOperand); |
| 10759 if (rightOperand != null) { | 11032 if (rightOperand != null) { |
| 10760 _overrideManager.enterScope(); | 11033 _overrideManager.enterScope(); |
| 10761 try { | 11034 try { |
| 10762 _promoteManager.enterScope(); | 11035 _promoteManager.enterScope(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 10782 if (rightOperand != null) { | 11055 if (rightOperand != null) { |
| 10783 _overrideManager.enterScope(); | 11056 _overrideManager.enterScope(); |
| 10784 try { | 11057 try { |
| 10785 _propagateFalseState(leftOperand); | 11058 _propagateFalseState(leftOperand); |
| 10786 rightOperand.accept(this); | 11059 rightOperand.accept(this); |
| 10787 } finally { | 11060 } finally { |
| 10788 _overrideManager.exitScope(); | 11061 _overrideManager.exitScope(); |
| 10789 } | 11062 } |
| 10790 } | 11063 } |
| 10791 } else { | 11064 } else { |
| 11065 // TODO(leafp): Handle this case | |
|
Brian Wilkerson
2015/11/21 16:12:22
I won't remember what this means outside the conte
Leaf
2015/12/01 21:49:11
Done.
| |
| 10792 safelyVisit(leftOperand); | 11066 safelyVisit(leftOperand); |
| 10793 safelyVisit(rightOperand); | 11067 safelyVisit(rightOperand); |
| 10794 } | 11068 } |
| 10795 node.accept(elementResolver); | 11069 node.accept(elementResolver); |
| 10796 node.accept(typeAnalyzer); | 11070 node.accept(typeAnalyzer); |
| 10797 return null; | 11071 return null; |
| 10798 } | 11072 } |
| 10799 | 11073 |
| 10800 @override | 11074 @override |
| 10801 Object visitBlockFunctionBody(BlockFunctionBody node) { | 11075 Object visitBlockFunctionBody(BlockFunctionBody node) { |
| 10802 safelyVisit(_commentBeforeFunction); | 11076 safelyVisit(_commentBeforeFunction); |
| 10803 _overrideManager.enterScope(); | 11077 _overrideManager.enterScope(); |
| 10804 try { | 11078 try { |
| 11079 inferenceContext.pushReturnContext(InferenceContext.get(node)); | |
| 10805 super.visitBlockFunctionBody(node); | 11080 super.visitBlockFunctionBody(node); |
| 10806 } finally { | 11081 } finally { |
| 10807 _overrideManager.exitScope(); | 11082 _overrideManager.exitScope(); |
| 11083 inferenceContext.popReturnContext(); | |
| 10808 } | 11084 } |
| 10809 return null; | 11085 return null; |
| 10810 } | 11086 } |
| 10811 | 11087 |
| 10812 @override | 11088 @override |
| 10813 Object visitBreakStatement(BreakStatement node) { | 11089 Object visitBreakStatement(BreakStatement node) { |
| 10814 // | 11090 // |
| 10815 // We do not visit the label because it needs to be visited in the context | 11091 // We do not visit the label because it needs to be visited in the context |
| 10816 // of the statement. | 11092 // of the statement. |
| 10817 // | 11093 // |
| 10818 node.accept(elementResolver); | 11094 node.accept(elementResolver); |
| 10819 node.accept(typeAnalyzer); | 11095 node.accept(typeAnalyzer); |
| 10820 return null; | 11096 return null; |
| 10821 } | 11097 } |
| 10822 | 11098 |
| 10823 @override | 11099 @override |
| 11100 Object visitCascadeExpression(CascadeExpression node) { | |
| 11101 InferenceContext.annotateNode(node.target, InferenceContext.get(node)); | |
| 11102 super.visitCascadeExpression(node); | |
| 11103 } | |
| 11104 | |
| 11105 @override | |
| 10824 Object visitClassDeclaration(ClassDeclaration node) { | 11106 Object visitClassDeclaration(ClassDeclaration node) { |
| 10825 // | 11107 // |
| 10826 // Resolve the metadata in the library scope. | 11108 // Resolve the metadata in the library scope. |
| 10827 // | 11109 // |
| 10828 if (node.metadata != null) { | 11110 if (node.metadata != null) { |
| 10829 node.metadata.accept(this); | 11111 node.metadata.accept(this); |
| 10830 } | 11112 } |
| 10831 _enclosingClassDeclaration = node; | 11113 _enclosingClassDeclaration = node; |
| 10832 // | 11114 // |
| 10833 // Continue the class resolution. | 11115 // Continue the class resolution. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10946 try { | 11228 try { |
| 10947 _promoteManager.enterScope(); | 11229 _promoteManager.enterScope(); |
| 10948 try { | 11230 try { |
| 10949 _propagateTrueState(condition); | 11231 _propagateTrueState(condition); |
| 10950 // Type promotion. | 11232 // Type promotion. |
| 10951 _promoteTypes(condition); | 11233 _promoteTypes(condition); |
| 10952 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); | 11234 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); |
| 10953 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( | 11235 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( |
| 10954 thenExpression); | 11236 thenExpression); |
| 10955 // Visit "then" expression. | 11237 // Visit "then" expression. |
| 11238 InferenceContext.annotateNode( | |
|
Jennifer Messerly
2015/11/23 22:11:57
might be worth a helper for this?
InferenceCo
Leaf
2015/12/01 21:49:11
Done.
| |
| 11239 thenExpression, InferenceContext.get(node)); | |
| 10956 thenExpression.accept(this); | 11240 thenExpression.accept(this); |
| 10957 } finally { | 11241 } finally { |
| 10958 _promoteManager.exitScope(); | 11242 _promoteManager.exitScope(); |
| 10959 } | 11243 } |
| 10960 } finally { | 11244 } finally { |
| 10961 _overrideManager.exitScope(); | 11245 _overrideManager.exitScope(); |
| 10962 } | 11246 } |
| 10963 } | 11247 } |
| 10964 Expression elseExpression = node.elseExpression; | 11248 Expression elseExpression = node.elseExpression; |
| 10965 if (elseExpression != null) { | 11249 if (elseExpression != null) { |
| 10966 _overrideManager.enterScope(); | 11250 _overrideManager.enterScope(); |
| 10967 try { | 11251 try { |
| 10968 _propagateFalseState(condition); | 11252 _propagateFalseState(condition); |
| 11253 InferenceContext.annotateNode( | |
| 11254 elseExpression, InferenceContext.get(node)); | |
| 10969 elseExpression.accept(this); | 11255 elseExpression.accept(this); |
| 10970 } finally { | 11256 } finally { |
| 10971 _overrideManager.exitScope(); | 11257 _overrideManager.exitScope(); |
| 10972 } | 11258 } |
| 10973 } | 11259 } |
| 10974 node.accept(elementResolver); | 11260 node.accept(elementResolver); |
| 10975 node.accept(typeAnalyzer); | 11261 node.accept(typeAnalyzer); |
| 10976 bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression); | 11262 bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression); |
| 10977 bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression); | 11263 bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression); |
| 10978 if (elseIsAbrupt && !thenIsAbrupt) { | 11264 if (elseIsAbrupt && !thenIsAbrupt) { |
| 10979 _propagateTrueState(condition); | 11265 _propagateTrueState(condition); |
| 10980 _propagateState(thenExpression); | 11266 _propagateState(thenExpression); |
| 10981 } else if (thenIsAbrupt && !elseIsAbrupt) { | 11267 } else if (thenIsAbrupt && !elseIsAbrupt) { |
| 10982 _propagateFalseState(condition); | 11268 _propagateFalseState(condition); |
| 10983 _propagateState(elseExpression); | 11269 _propagateState(elseExpression); |
| 10984 } | 11270 } |
| 10985 return null; | 11271 return null; |
| 10986 } | 11272 } |
| 10987 | 11273 |
| 10988 @override | 11274 @override |
| 10989 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 11275 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 10990 ExecutableElement outerFunction = _enclosingFunction; | 11276 ExecutableElement outerFunction = _enclosingFunction; |
| 10991 try { | 11277 try { |
| 10992 _enclosingFunction = node.element; | 11278 _enclosingFunction = node.element; |
| 11279 DartType type = _enclosingFunction.type; | |
| 11280 if (type is FunctionType) { | |
|
Jennifer Messerly
2015/11/23 22:11:58
I think this would always be the case for a constr
Leaf
2015/12/01 21:49:11
Done.
| |
| 11281 _inferFormalParameterList(node.parameters, type); | |
|
Jennifer Messerly
2015/11/23 22:11:57
was just chatting about this--I'm not sure this co
Leaf
2015/12/01 21:49:11
Done.
| |
| 11282 InferenceContext.annotateNode(node.body, type.returnType); | |
| 11283 } | |
| 10993 super.visitConstructorDeclaration(node); | 11284 super.visitConstructorDeclaration(node); |
| 10994 } finally { | 11285 } finally { |
| 10995 _enclosingFunction = outerFunction; | 11286 _enclosingFunction = outerFunction; |
| 10996 } | 11287 } |
| 10997 ConstructorElementImpl constructor = node.element; | 11288 ConstructorElementImpl constructor = node.element; |
| 10998 constructor.constantInitializers = | 11289 constructor.constantInitializers = |
| 10999 new ConstantAstCloner().cloneNodeList(node.initializers); | 11290 new ConstantAstCloner().cloneNodeList(node.initializers); |
| 11000 return null; | 11291 return null; |
| 11001 } | 11292 } |
| 11002 | 11293 |
| 11003 @override | 11294 @override |
| 11004 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 11295 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 11005 // | 11296 // |
| 11006 // We visit the expression, but do not visit the field name because it needs | 11297 // We visit the expression, but do not visit the field name because it needs |
| 11007 // to be visited in the context of the constructor field initializer node. | 11298 // to be visited in the context of the constructor field initializer node. |
| 11008 // | 11299 // |
| 11300 FieldElement fieldElement = enclosingClass.getField(node.fieldName.name); | |
|
Jennifer Messerly
2015/11/23 22:11:57
Does `fieldName.staticElement` give you the field
Leaf
2015/11/24 19:32:12
Not set until the elementResolver runs below. I co
Jennifer Messerly
2015/11/24 20:10:57
ah, interesting. In this case I think re-ordering
Leaf
2015/12/01 21:49:11
Yes, it's fine here and now, but I feel like every
| |
| 11301 InferenceContext.annotateNode(node.expression, fieldElement?.type); | |
| 11009 safelyVisit(node.expression); | 11302 safelyVisit(node.expression); |
| 11010 node.accept(elementResolver); | 11303 node.accept(elementResolver); |
| 11011 node.accept(typeAnalyzer); | 11304 node.accept(typeAnalyzer); |
| 11012 return null; | 11305 return null; |
| 11013 } | 11306 } |
| 11014 | 11307 |
| 11015 @override | 11308 @override |
| 11016 Object visitConstructorName(ConstructorName node) { | 11309 Object visitConstructorName(ConstructorName node) { |
| 11017 // | 11310 // |
| 11018 // We do not visit either the type name, because it won't be visited anyway, | 11311 // We do not visit either the type name, because it won't be visited anyway, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 11030 // We do not visit the label because it needs to be visited in the context | 11323 // We do not visit the label because it needs to be visited in the context |
| 11031 // of the statement. | 11324 // of the statement. |
| 11032 // | 11325 // |
| 11033 node.accept(elementResolver); | 11326 node.accept(elementResolver); |
| 11034 node.accept(typeAnalyzer); | 11327 node.accept(typeAnalyzer); |
| 11035 return null; | 11328 return null; |
| 11036 } | 11329 } |
| 11037 | 11330 |
| 11038 @override | 11331 @override |
| 11039 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 11332 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 11333 InferenceContext.annotateNode( | |
| 11334 node.defaultValue, node.parameter.element?.type); | |
| 11040 super.visitDefaultFormalParameter(node); | 11335 super.visitDefaultFormalParameter(node); |
| 11041 ParameterElement element = node.element; | 11336 ParameterElement element = node.element; |
| 11042 if (element.initializer != null && node.defaultValue != null) { | 11337 if (element.initializer != null && node.defaultValue != null) { |
| 11043 (element.initializer as FunctionElementImpl).returnType = | 11338 (element.initializer as FunctionElementImpl).returnType = |
| 11044 node.defaultValue.staticType; | 11339 node.defaultValue.staticType; |
| 11045 } | 11340 } |
| 11046 FormalParameterList parent = node.parent; | 11341 FormalParameterList parent = node.parent; |
| 11047 AstNode grandparent = parent.parent; | 11342 AstNode grandparent = parent.parent; |
| 11048 if (grandparent is ConstructorDeclaration && | 11343 if (grandparent is ConstructorDeclaration && |
| 11049 grandparent.constKeyword != null) { | 11344 grandparent.constKeyword != null) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11108 } | 11403 } |
| 11109 | 11404 |
| 11110 @override | 11405 @override |
| 11111 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { | 11406 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| 11112 safelyVisit(_commentBeforeFunction); | 11407 safelyVisit(_commentBeforeFunction); |
| 11113 if (resolveOnlyCommentInFunctionBody) { | 11408 if (resolveOnlyCommentInFunctionBody) { |
| 11114 return null; | 11409 return null; |
| 11115 } | 11410 } |
| 11116 _overrideManager.enterScope(); | 11411 _overrideManager.enterScope(); |
| 11117 try { | 11412 try { |
| 11413 InferenceContext.annotateNode( | |
| 11414 node.expression, InferenceContext.get(node)); | |
| 11118 super.visitExpressionFunctionBody(node); | 11415 super.visitExpressionFunctionBody(node); |
| 11119 } finally { | 11416 } finally { |
| 11120 _overrideManager.exitScope(); | 11417 _overrideManager.exitScope(); |
| 11121 } | 11418 } |
| 11122 return null; | 11419 return null; |
| 11123 } | 11420 } |
| 11124 | 11421 |
| 11125 @override | 11422 @override |
| 11126 Object visitFieldDeclaration(FieldDeclaration node) { | 11423 Object visitFieldDeclaration(FieldDeclaration node) { |
| 11127 _overrideManager.enterScope(); | 11424 _overrideManager.enterScope(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 11147 return null; | 11444 return null; |
| 11148 } | 11445 } |
| 11149 | 11446 |
| 11150 @override | 11447 @override |
| 11151 void visitForEachStatementInScope(ForEachStatement node) { | 11448 void visitForEachStatementInScope(ForEachStatement node) { |
| 11152 // | 11449 // |
| 11153 // We visit the iterator before the loop variable because the loop variable | 11450 // We visit the iterator before the loop variable because the loop variable |
| 11154 // cannot be in scope while visiting the iterator. | 11451 // cannot be in scope while visiting the iterator. |
| 11155 // | 11452 // |
| 11156 Expression iterable = node.iterable; | 11453 Expression iterable = node.iterable; |
| 11157 safelyVisit(iterable); | |
| 11158 DeclaredIdentifier loopVariable = node.loopVariable; | 11454 DeclaredIdentifier loopVariable = node.loopVariable; |
| 11159 SimpleIdentifier identifier = node.identifier; | 11455 SimpleIdentifier identifier = node.identifier; |
| 11456 if (loopVariable?.type?.type != null) { | |
| 11457 InterfaceType targetType = (node.awaitKeyword == null) | |
| 11458 ? typeProvider.iterableType | |
| 11459 : typeProvider.streamType; | |
| 11460 InferenceContext.annotateNode( | |
| 11461 iterable, targetType.substitute4([loopVariable.type.type])); | |
| 11462 } | |
| 11463 safelyVisit(iterable); | |
| 11160 safelyVisit(loopVariable); | 11464 safelyVisit(loopVariable); |
| 11161 safelyVisit(identifier); | 11465 safelyVisit(identifier); |
| 11162 Statement body = node.body; | 11466 Statement body = node.body; |
| 11163 if (body != null) { | 11467 if (body != null) { |
| 11164 _overrideManager.enterScope(); | 11468 _overrideManager.enterScope(); |
| 11165 try { | 11469 try { |
| 11166 if (loopVariable != null && iterable != null) { | 11470 if (loopVariable != null && iterable != null) { |
| 11167 LocalVariableElement loopElement = loopVariable.element; | 11471 LocalVariableElement loopElement = loopVariable.element; |
| 11168 if (loopElement != null) { | 11472 if (loopElement != null) { |
| 11169 DartType propagatedType = null; | 11473 DartType propagatedType = null; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11222 // TODO(brianwilkerson) If the loop can only be exited because the condition | 11526 // TODO(brianwilkerson) If the loop can only be exited because the condition |
| 11223 // is false, then propagateFalseState(condition); | 11527 // is false, then propagateFalseState(condition); |
| 11224 } | 11528 } |
| 11225 | 11529 |
| 11226 @override | 11530 @override |
| 11227 Object visitFunctionDeclaration(FunctionDeclaration node) { | 11531 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 11228 ExecutableElement outerFunction = _enclosingFunction; | 11532 ExecutableElement outerFunction = _enclosingFunction; |
| 11229 try { | 11533 try { |
| 11230 SimpleIdentifier functionName = node.name; | 11534 SimpleIdentifier functionName = node.name; |
| 11231 _enclosingFunction = functionName.staticElement as ExecutableElement; | 11535 _enclosingFunction = functionName.staticElement as ExecutableElement; |
| 11536 InferenceContext.annotateNode( | |
| 11537 node.functionExpression, _enclosingFunction.type); | |
| 11232 super.visitFunctionDeclaration(node); | 11538 super.visitFunctionDeclaration(node); |
| 11233 } finally { | 11539 } finally { |
| 11234 _enclosingFunction = outerFunction; | 11540 _enclosingFunction = outerFunction; |
| 11235 } | 11541 } |
| 11236 return null; | 11542 return null; |
| 11237 } | 11543 } |
| 11238 | 11544 |
| 11239 @override | 11545 @override |
| 11240 Object visitFunctionExpression(FunctionExpression node) { | 11546 Object visitFunctionExpression(FunctionExpression node) { |
| 11241 ExecutableElement outerFunction = _enclosingFunction; | 11547 ExecutableElement outerFunction = _enclosingFunction; |
| 11242 try { | 11548 try { |
| 11243 _enclosingFunction = node.element; | 11549 _enclosingFunction = node.element; |
| 11244 _overrideManager.enterScope(); | 11550 _overrideManager.enterScope(); |
| 11245 try { | 11551 try { |
| 11552 DartType functionType = InferenceContext.get(node); | |
| 11553 if (functionType is FunctionType) { | |
| 11554 _inferFormalParameterList(node.parameters, functionType); | |
| 11555 InferenceContext.annotateNode(node.body, functionType.returnType); | |
| 11556 } | |
| 11246 super.visitFunctionExpression(node); | 11557 super.visitFunctionExpression(node); |
| 11247 } finally { | 11558 } finally { |
| 11248 _overrideManager.exitScope(); | 11559 _overrideManager.exitScope(); |
| 11249 } | 11560 } |
| 11250 } finally { | 11561 } finally { |
| 11251 _enclosingFunction = outerFunction; | 11562 _enclosingFunction = outerFunction; |
| 11252 } | 11563 } |
| 11253 return null; | 11564 return null; |
| 11254 } | 11565 } |
| 11255 | 11566 |
| 11256 @override | 11567 @override |
| 11257 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 11568 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 11258 safelyVisit(node.function); | 11569 safelyVisit(node.function); |
| 11259 node.accept(elementResolver); | 11570 node.accept(elementResolver); |
| 11260 _inferFunctionExpressionsParametersTypes(node.argumentList); | 11571 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 11572 InferenceContext.annotateNode(node.argumentList, node.function.staticType); | |
| 11261 safelyVisit(node.argumentList); | 11573 safelyVisit(node.argumentList); |
| 11262 node.accept(typeAnalyzer); | 11574 node.accept(typeAnalyzer); |
| 11263 return null; | 11575 return null; |
| 11264 } | 11576 } |
| 11265 | 11577 |
| 11266 @override | 11578 @override |
| 11267 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 11579 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 11268 // Resolve the metadata in the library scope. | 11580 // Resolve the metadata in the library scope. |
| 11269 if (node.metadata != null) { | 11581 if (node.metadata != null) { |
| 11270 node.metadata.accept(this); | 11582 node.metadata.accept(this); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11338 List<Map<VariableElement, DartType>> perBranchOverrides = | 11650 List<Map<VariableElement, DartType>> perBranchOverrides = |
| 11339 new List<Map<VariableElement, DartType>>(); | 11651 new List<Map<VariableElement, DartType>>(); |
| 11340 perBranchOverrides.add(thenOverrides); | 11652 perBranchOverrides.add(thenOverrides); |
| 11341 perBranchOverrides.add(elseOverrides); | 11653 perBranchOverrides.add(elseOverrides); |
| 11342 _overrideManager.mergeOverrides(perBranchOverrides); | 11654 _overrideManager.mergeOverrides(perBranchOverrides); |
| 11343 } | 11655 } |
| 11344 return null; | 11656 return null; |
| 11345 } | 11657 } |
| 11346 | 11658 |
| 11347 @override | 11659 @override |
| 11660 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | |
| 11661 DartType contextType = InferenceContext.get(node); | |
| 11662 if (contextType is InterfaceType && | |
| 11663 contextType.typeArguments != null && | |
| 11664 contextType.typeArguments.length > 0) { | |
| 11665 TypeName classTypeName = node.constructorName.type; | |
| 11666 if (classTypeName.typeArguments == null) { | |
| 11667 List<DartType> targs = | |
| 11668 inferenceContext.matchTypes(classTypeName.type, contextType); | |
| 11669 if (targs != null && targs.any((t) => !t.isDynamic)) { | |
| 11670 ClassElement classElement = classTypeName.type.element; | |
| 11671 InterfaceType rawType = classElement.type; | |
| 11672 InterfaceType fullType = | |
| 11673 rawType.substitute2(targs, rawType.typeArguments); | |
| 11674 // The element resolver uses the type on the constructor name, so | |
| 11675 // infer it first | |
| 11676 typeAnalyzer.inferConstructorName(node.constructorName, fullType); | |
| 11677 safelyVisit(node.constructorName); | |
| 11678 ConstructorElement invokedConstructor = | |
| 11679 node.constructorName.staticElement; | |
| 11680 FunctionType rawConstructorType = invokedConstructor.type; | |
| 11681 FunctionType constructorType = rawConstructorType.substitute2( | |
| 11682 targs, rawConstructorType.typeArguments); | |
| 11683 InferenceContext.annotateNode(node.argumentList, constructorType); | |
| 11684 safelyVisit(node.argumentList); | |
| 11685 InferenceContext.annotateNode(node, fullType); | |
| 11686 node.accept(elementResolver); | |
| 11687 node.accept(typeAnalyzer); | |
| 11688 return null; | |
| 11689 } | |
| 11690 } else { | |
| 11691 InferenceContext.clear(node); | |
| 11692 } | |
| 11693 } | |
| 11694 super.visitInstanceCreationExpression(node); | |
| 11695 return null; | |
| 11696 } | |
| 11697 | |
| 11698 @override | |
| 11348 Object visitLabel(Label node) => null; | 11699 Object visitLabel(Label node) => null; |
| 11349 | 11700 |
| 11350 @override | 11701 @override |
| 11351 Object visitLibraryIdentifier(LibraryIdentifier node) => null; | 11702 Object visitLibraryIdentifier(LibraryIdentifier node) => null; |
| 11352 | 11703 |
| 11353 @override | 11704 @override |
| 11705 Object visitListLiteral(ListLiteral node) { | |
| 11706 DartType contextType = InferenceContext.get(node); | |
| 11707 if (node.typeArguments == null && contextType is InterfaceType) { | |
| 11708 InterfaceType listD = | |
| 11709 typeProvider.listType.substitute4([typeProvider.dynamicType]); | |
| 11710 List<DartType> targs = inferenceContext.matchTypes(listD, contextType); | |
| 11711 if (targs != null && | |
| 11712 targs.length == 1 && | |
| 11713 targs.any((t) => !t.isDynamic)) { | |
| 11714 DartType eType = targs[0]; | |
| 11715 InterfaceType listT = typeProvider.listType.substitute4([eType]); | |
| 11716 for (Expression child in node.elements) { | |
| 11717 InferenceContext.annotateNode(child, eType); | |
| 11718 } | |
| 11719 InferenceContext.annotateNode(node, listT); | |
| 11720 } else { | |
| 11721 InferenceContext.clear(node); | |
| 11722 } | |
| 11723 } | |
| 11724 super.visitListLiteral(node); | |
| 11725 return null; | |
| 11726 } | |
| 11727 | |
| 11728 @override | |
| 11729 Object visitMapLiteral(MapLiteral node) { | |
| 11730 DartType contextType = InferenceContext.get(node); | |
| 11731 if (node.typeArguments == null && contextType is InterfaceType) { | |
| 11732 InterfaceType mapD = typeProvider.mapType | |
| 11733 .substitute4([typeProvider.dynamicType, typeProvider.dynamicType]); | |
| 11734 List<DartType> targs = inferenceContext.matchTypes(mapD, contextType); | |
| 11735 if (targs != null && | |
| 11736 targs.length == 2 && | |
| 11737 targs.any((t) => !t.isDynamic)) { | |
| 11738 DartType kType = targs[0]; | |
| 11739 DartType vType = targs[1]; | |
| 11740 InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]); | |
| 11741 for (MapLiteralEntry entry in node.entries) { | |
| 11742 InferenceContext.annotateNode(entry.key, kType); | |
| 11743 InferenceContext.annotateNode(entry.value, vType); | |
| 11744 } | |
| 11745 InferenceContext.annotateNode(node, mapT); | |
| 11746 } else { | |
| 11747 InferenceContext.clear(node); | |
| 11748 } | |
| 11749 } | |
| 11750 super.visitMapLiteral(node); | |
| 11751 return null; | |
| 11752 } | |
| 11753 | |
| 11754 @override | |
| 11354 Object visitMethodDeclaration(MethodDeclaration node) { | 11755 Object visitMethodDeclaration(MethodDeclaration node) { |
| 11355 ExecutableElement outerFunction = _enclosingFunction; | 11756 ExecutableElement outerFunction = _enclosingFunction; |
| 11356 try { | 11757 try { |
| 11357 _enclosingFunction = node.element; | 11758 _enclosingFunction = node.element; |
| 11759 _inferFormalParameterList(node.parameters, node.element.type); | |
| 11760 InferenceContext.annotateNode(node.body, node.element.type?.returnType); | |
| 11358 super.visitMethodDeclaration(node); | 11761 super.visitMethodDeclaration(node); |
| 11359 } finally { | 11762 } finally { |
| 11360 _enclosingFunction = outerFunction; | 11763 _enclosingFunction = outerFunction; |
| 11361 } | 11764 } |
| 11362 return null; | 11765 return null; |
| 11363 } | 11766 } |
| 11364 | 11767 |
| 11365 @override | 11768 @override |
| 11366 Object visitMethodInvocation(MethodInvocation node) { | 11769 Object visitMethodInvocation(MethodInvocation node) { |
| 11367 // | 11770 // |
| 11368 // We visit the target and argument list, but do not visit the method name | 11771 // We visit the target and argument list, but do not visit the method name |
| 11369 // because it needs to be visited in the context of the invocation. | 11772 // because it needs to be visited in the context of the invocation. |
| 11370 // | 11773 // |
| 11371 safelyVisit(node.target); | 11774 safelyVisit(node.target); |
| 11372 node.accept(elementResolver); | 11775 node.accept(elementResolver); |
| 11373 _inferFunctionExpressionsParametersTypes(node.argumentList); | 11776 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 11777 if (node.methodName.staticElement is ExecutableElement) { | |
|
Jennifer Messerly
2015/11/23 22:11:57
suggestion, if you save this into a variable you c
Leaf
2015/12/01 21:49:10
Done.
| |
| 11778 DartType type = (node.methodName.staticElement as ExecutableElement).type; | |
| 11779 InferenceContext.annotateNode(node.argumentList, type); | |
| 11780 } | |
| 11374 safelyVisit(node.argumentList); | 11781 safelyVisit(node.argumentList); |
| 11375 node.accept(typeAnalyzer); | 11782 node.accept(typeAnalyzer); |
| 11376 return null; | 11783 return null; |
| 11377 } | 11784 } |
| 11378 | 11785 |
| 11379 @override | 11786 @override |
| 11787 Object visitNamedExpression(NamedExpression node) { | |
| 11788 InferenceContext.annotateNode(node.expression, InferenceContext.get(node)); | |
| 11789 super.visitNamedExpression(node); | |
|
Jennifer Messerly
2015/11/23 22:11:57
not sure if Brian got tired of pointing it out ...
Leaf
2015/12/01 21:49:10
Done.
| |
| 11790 } | |
| 11791 | |
| 11792 @override | |
| 11380 Object visitNode(AstNode node) { | 11793 Object visitNode(AstNode node) { |
| 11381 node.visitChildren(this); | 11794 node.visitChildren(this); |
| 11382 node.accept(elementResolver); | 11795 node.accept(elementResolver); |
| 11383 node.accept(typeAnalyzer); | 11796 node.accept(typeAnalyzer); |
| 11384 return null; | 11797 return null; |
| 11385 } | 11798 } |
| 11386 | 11799 |
| 11387 @override | 11800 @override |
| 11801 Object visitParenthesizedExpression(ParenthesizedExpression node) { | |
| 11802 InferenceContext.annotateNode(node.expression, InferenceContext.get(node)); | |
| 11803 super.visitParenthesizedExpression(node); | |
| 11804 } | |
| 11805 | |
| 11806 @override | |
| 11388 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 11807 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 11389 // | 11808 // |
| 11390 // We visit the prefix, but do not visit the identifier because it needs to | 11809 // We visit the prefix, but do not visit the identifier because it needs to |
| 11391 // be visited in the context of the prefix. | 11810 // be visited in the context of the prefix. |
| 11392 // | 11811 // |
| 11393 safelyVisit(node.prefix); | 11812 safelyVisit(node.prefix); |
| 11394 node.accept(elementResolver); | 11813 node.accept(elementResolver); |
| 11395 node.accept(typeAnalyzer); | 11814 node.accept(typeAnalyzer); |
| 11396 return null; | 11815 return null; |
| 11397 } | 11816 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 11409 } | 11828 } |
| 11410 | 11829 |
| 11411 @override | 11830 @override |
| 11412 Object visitRedirectingConstructorInvocation( | 11831 Object visitRedirectingConstructorInvocation( |
| 11413 RedirectingConstructorInvocation node) { | 11832 RedirectingConstructorInvocation node) { |
| 11414 // | 11833 // |
| 11415 // We visit the argument list, but do not visit the optional identifier | 11834 // We visit the argument list, but do not visit the optional identifier |
| 11416 // because it needs to be visited in the context of the constructor | 11835 // because it needs to be visited in the context of the constructor |
| 11417 // invocation. | 11836 // invocation. |
| 11418 // | 11837 // |
| 11838 InferenceContext.annotateNode(node.argumentList, node.staticElement?.type); | |
| 11419 safelyVisit(node.argumentList); | 11839 safelyVisit(node.argumentList); |
| 11420 node.accept(elementResolver); | 11840 node.accept(elementResolver); |
| 11421 node.accept(typeAnalyzer); | 11841 node.accept(typeAnalyzer); |
| 11422 return null; | 11842 return null; |
| 11423 } | 11843 } |
| 11424 | 11844 |
| 11425 @override | 11845 @override |
| 11846 Object visitReturnStatement(ReturnStatement node) { | |
| 11847 InferenceContext.annotateNode( | |
| 11848 node.expression, inferenceContext.returnContext); | |
| 11849 super.visitReturnStatement(node); | |
| 11850 } | |
| 11851 | |
| 11852 @override | |
| 11426 Object visitShowCombinator(ShowCombinator node) => null; | 11853 Object visitShowCombinator(ShowCombinator node) => null; |
| 11427 | 11854 |
| 11428 @override | 11855 @override |
| 11429 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 11856 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 11430 // | 11857 // |
| 11431 // We visit the argument list, but do not visit the optional identifier | 11858 // We visit the argument list, but do not visit the optional identifier |
| 11432 // because it needs to be visited in the context of the constructor | 11859 // because it needs to be visited in the context of the constructor |
| 11433 // invocation. | 11860 // invocation. |
| 11434 // | 11861 // |
| 11862 InferenceContext.annotateNode(node.argumentList, node.staticElement?.type); | |
| 11435 safelyVisit(node.argumentList); | 11863 safelyVisit(node.argumentList); |
| 11436 node.accept(elementResolver); | 11864 node.accept(elementResolver); |
| 11437 node.accept(typeAnalyzer); | 11865 node.accept(typeAnalyzer); |
| 11438 return null; | 11866 return null; |
| 11439 } | 11867 } |
| 11440 | 11868 |
| 11441 @override | 11869 @override |
| 11442 Object visitSwitchCase(SwitchCase node) { | 11870 Object visitSwitchCase(SwitchCase node) { |
| 11443 _overrideManager.enterScope(); | 11871 _overrideManager.enterScope(); |
| 11444 try { | 11872 try { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 11472 _overrideManager.applyOverrides(overrides); | 11900 _overrideManager.applyOverrides(overrides); |
| 11473 } | 11901 } |
| 11474 return null; | 11902 return null; |
| 11475 } | 11903 } |
| 11476 | 11904 |
| 11477 @override | 11905 @override |
| 11478 Object visitTypeName(TypeName node) => null; | 11906 Object visitTypeName(TypeName node) => null; |
| 11479 | 11907 |
| 11480 @override | 11908 @override |
| 11481 Object visitVariableDeclaration(VariableDeclaration node) { | 11909 Object visitVariableDeclaration(VariableDeclaration node) { |
| 11910 InferenceContext.annotateNode(node.initializer, InferenceContext.get(node)); | |
| 11482 super.visitVariableDeclaration(node); | 11911 super.visitVariableDeclaration(node); |
| 11483 VariableElement element = node.element; | 11912 VariableElement element = node.element; |
| 11484 if (element.initializer != null && node.initializer != null) { | 11913 if (element.initializer != null && node.initializer != null) { |
| 11485 (element.initializer as FunctionElementImpl).returnType = | 11914 (element.initializer as FunctionElementImpl).returnType = |
| 11486 node.initializer.staticType; | 11915 node.initializer.staticType; |
| 11487 } | 11916 } |
| 11488 // Note: in addition to cloning the initializers for const variables, we | 11917 // Note: in addition to cloning the initializers for const variables, we |
| 11489 // have to clone the initializers for non-static final fields (because if | 11918 // have to clone the initializers for non-static final fields (because if |
| 11490 // they occur in a class with a const constructor, they will be needed to | 11919 // they occur in a class with a const constructor, they will be needed to |
| 11491 // evaluate the const constructor). | 11920 // evaluate the const constructor). |
| 11492 if ((element.isConst || | 11921 if ((element.isConst || |
| 11493 (element is FieldElement && | 11922 (element is FieldElement && |
| 11494 element.isFinal && | 11923 element.isFinal && |
| 11495 !element.isStatic)) && | 11924 !element.isStatic)) && |
| 11496 node.initializer != null) { | 11925 node.initializer != null) { |
| 11497 (element as ConstVariableElement).constantInitializer = | 11926 (element as ConstVariableElement).constantInitializer = |
| 11498 new ConstantAstCloner().cloneNode(node.initializer); | 11927 new ConstantAstCloner().cloneNode(node.initializer); |
| 11499 } | 11928 } |
| 11500 return null; | 11929 return null; |
| 11501 } | 11930 } |
| 11502 | 11931 |
| 11932 @override visitVariableDeclarationList(VariableDeclarationList node) { | |
| 11933 for (VariableDeclaration decl in node.variables) { | |
| 11934 InferenceContext.annotateNode(decl, node.type?.type); | |
| 11935 } | |
| 11936 super.visitVariableDeclarationList(node); | |
| 11937 } | |
| 11938 | |
| 11503 @override | 11939 @override |
| 11504 Object visitWhileStatement(WhileStatement node) { | 11940 Object visitWhileStatement(WhileStatement node) { |
| 11505 // Note: since we don't call the base class, we have to maintain | 11941 // Note: since we don't call the base class, we have to maintain |
| 11506 // _implicitLabelScope ourselves. | 11942 // _implicitLabelScope ourselves. |
| 11507 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 11943 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
| 11508 try { | 11944 try { |
| 11509 _implicitLabelScope = _implicitLabelScope.nest(node); | 11945 _implicitLabelScope = _implicitLabelScope.nest(node); |
| 11510 Expression condition = node.condition; | 11946 Expression condition = node.condition; |
| 11511 safelyVisit(condition); | 11947 safelyVisit(condition); |
| 11512 Statement body = node.body; | 11948 Statement body = node.body; |
| 11513 if (body != null) { | 11949 if (body != null) { |
| 11514 _overrideManager.enterScope(); | 11950 _overrideManager.enterScope(); |
| 11515 try { | 11951 try { |
| 11516 _propagateTrueState(condition); | 11952 _propagateTrueState(condition); |
| 11517 visitStatementInScope(body); | 11953 visitStatementInScope(body); |
| 11518 } finally { | 11954 } finally { |
| 11519 _overrideManager.exitScope(); | 11955 _overrideManager.exitScope(); |
| 11520 } | 11956 } |
| 11521 } | 11957 } |
| 11522 } finally { | 11958 } finally { |
| 11523 _implicitLabelScope = outerImplicitScope; | 11959 _implicitLabelScope = outerImplicitScope; |
| 11524 } | 11960 } |
| 11525 // TODO(brianwilkerson) If the loop can only be exited because the condition | 11961 // TODO(brianwilkerson) If the loop can only be exited because the condition |
| 11526 // is false, then propagateFalseState(condition); | 11962 // is false, then propagateFalseState(condition); |
| 11527 node.accept(elementResolver); | 11963 node.accept(elementResolver); |
| 11528 node.accept(typeAnalyzer); | 11964 node.accept(typeAnalyzer); |
| 11529 return null; | 11965 return null; |
| 11530 } | 11966 } |
| 11531 | 11967 |
| 11968 @override | |
| 11969 Object visitYieldStatement(YieldStatement node) { | |
| 11970 DartType returnType = inferenceContext.returnContext; | |
| 11971 if (returnType != null && _enclosingFunction != null) { | |
| 11972 // If we're not in a generator ([a]sync*, then we shouldn't have a yield. | |
| 11973 // so don't infer | |
| 11974 if (_enclosingFunction.isGenerator) { | |
| 11975 // If this is a yield*, then we just propagate the return type downwards | |
| 11976 DartType type = returnType; | |
| 11977 // If this just a yield, then we need to get the element type | |
| 11978 if (node.star == null) { | |
| 11979 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> | |
| 11980 InterfaceType wrapperD = (_enclosingFunction.isSynchronous) | |
|
Jennifer Messerly
2015/11/23 22:11:57
nit: parens not needed
Leaf
2015/12/01 21:49:11
Done.
| |
| 11981 ? typeProvider.iterableDynamicType | |
| 11982 : typeProvider.streamDynamicType; | |
| 11983 // Match the types to instantiate the type arguments if possible | |
| 11984 List<DartType> targs = | |
| 11985 inferenceContext.matchTypes(wrapperD, returnType); | |
| 11986 type = (targs?.length == 1) ? targs[0] : null; | |
| 11987 } | |
| 11988 InferenceContext.annotateNode(node.expression, type); | |
| 11989 } | |
| 11990 } | |
| 11991 super.visitYieldStatement(node); | |
|
Brian Wilkerson
2015/11/21 16:12:22
Missing return
Leaf
2015/11/24 19:32:12
Just a meta-comment: this is one of those analyzer
Brian Wilkerson
2015/11/24 21:17:57
That depends on the IDE. I don't know of any way t
Leaf
2015/12/01 21:49:10
Done.
| |
| 11992 } | |
| 11993 | |
| 11532 /** | 11994 /** |
| 11533 * Checks each promoted variable in the current scope for compliance with the following | 11995 * Checks each promoted variable in the current scope for compliance with the following |
| 11534 * specification statement: | 11996 * specification statement: |
| 11535 * | 11997 * |
| 11536 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t hen the variable | 11998 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t hen the variable |
| 11537 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. | 11999 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. |
| 11538 */ | 12000 */ |
| 11539 void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( | 12001 void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( |
| 11540 AstNode target) { | 12002 AstNode target) { |
| 11541 for (Element element in _promoteManager.promotedElements) { | 12003 for (Element element in _promoteManager.promotedElements) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11616 List<ParameterElement> onDataParameters = onDataType.parameters; | 12078 List<ParameterElement> onDataParameters = onDataType.parameters; |
| 11617 if (onDataParameters == null || onDataParameters.isEmpty) { | 12079 if (onDataParameters == null || onDataParameters.isEmpty) { |
| 11618 return null; | 12080 return null; |
| 11619 } | 12081 } |
| 11620 return onDataParameters[0].type; | 12082 return onDataParameters[0].type; |
| 11621 } | 12083 } |
| 11622 } | 12084 } |
| 11623 return null; | 12085 return null; |
| 11624 } | 12086 } |
| 11625 | 12087 |
| 12088 void _inferFormalParameterList(FormalParameterList node, DartType type) { | |
| 12089 if (typeAnalyzer.inferFormalParameterList(node, type)) { | |
| 12090 // TODO(leafp): This gets dropped on the floor if we're in the field | |
| 12091 // inference task. We should probably keep these infos. | |
| 12092 inferenceContext.recordInference(node.parent, type); | |
| 12093 } | |
| 12094 } | |
| 12095 | |
| 11626 /** | 12096 /** |
| 11627 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its | 12097 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its |
| 11628 * required type is [FunctionType], then infer parameters types from [Function Type]. | 12098 * required type is [FunctionType], then infer parameters types from [Function Type]. |
| 11629 */ | 12099 */ |
| 11630 void _inferFunctionExpressionParametersTypes( | 12100 void _inferFunctionExpressionParametersTypes( |
| 11631 Expression mayBeClosure, DartType mayByFunctionType) { | 12101 Expression mayBeClosure, DartType mayByFunctionType) { |
| 11632 // prepare closure | 12102 // prepare closure |
| 11633 if (mayBeClosure is! FunctionExpression) { | 12103 if (mayBeClosure is! FunctionExpression) { |
| 11634 return; | 12104 return; |
| 11635 } | 12105 } |
| (...skipping 3913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15549 nonFields.add(node); | 16019 nonFields.add(node); |
| 15550 return null; | 16020 return null; |
| 15551 } | 16021 } |
| 15552 | 16022 |
| 15553 @override | 16023 @override |
| 15554 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 16024 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 15555 | 16025 |
| 15556 @override | 16026 @override |
| 15557 Object visitWithClause(WithClause node) => null; | 16027 Object visitWithClause(WithClause node) => null; |
| 15558 } | 16028 } |
| OLD | NEW |