| 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 analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 4679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4690 * of all return statements in a lambda. | 4690 * of all return statements in a lambda. |
| 4691 * | 4691 * |
| 4692 * This will always be kept in sync with [_returnStack]. | 4692 * This will always be kept in sync with [_returnStack]. |
| 4693 */ | 4693 */ |
| 4694 final List<DartType> _inferredReturn = <DartType>[]; | 4694 final List<DartType> _inferredReturn = <DartType>[]; |
| 4695 | 4695 |
| 4696 /** | 4696 /** |
| 4697 * A stack of return types for all of the enclosing | 4697 * A stack of return types for all of the enclosing |
| 4698 * functions and methods. | 4698 * functions and methods. |
| 4699 */ | 4699 */ |
| 4700 // TODO(leafp) Handle the implicit union type for Futures | |
| 4701 // https://github.com/dart-lang/sdk/issues/25322 | |
| 4702 final List<DartType> _returnStack = <DartType>[]; | 4700 final List<DartType> _returnStack = <DartType>[]; |
| 4703 | 4701 |
| 4704 InferenceContext._(this._errorReporter, TypeProvider typeProvider, | 4702 InferenceContext._(this._errorReporter, TypeProvider typeProvider, |
| 4705 this._typeSystem, this._inferenceHints) | 4703 this._typeSystem, this._inferenceHints) |
| 4706 : _typeProvider = typeProvider; | 4704 : _typeProvider = typeProvider; |
| 4707 | 4705 |
| 4708 /** | 4706 /** |
| 4709 * Get the return type of the current enclosing function, if any. | 4707 * Get the return type of the current enclosing function, if any. |
| 4710 * | 4708 * |
| 4711 * The type returned for a function is the type that is expected | 4709 * The type returned for a function is the type that is expected |
| 4712 * to be used in a return or yield context. For ordinary functions | 4710 * to be used in a return or yield context. For ordinary functions |
| 4713 * this is the same as the return type of the function. For async | 4711 * this is the same as the return type of the function. For async |
| 4714 * functions returning Future<T> and for generator functions | 4712 * functions returning Future<T> and for generator functions |
| 4715 * returning Stream<T> or Iterable<T>, this is T. | 4713 * returning Stream<T> or Iterable<T>, this is T. |
| 4716 */ | 4714 */ |
| 4717 DartType get returnContext => | 4715 DartType get returnContext => |
| 4718 _returnStack.isNotEmpty ? _returnStack.last : null; | 4716 _returnStack.isNotEmpty ? _returnStack.last : null; |
| 4719 | 4717 |
| 4720 /** | 4718 /** |
| 4721 * Records the type of the expression of a return statement. | 4719 * Records the type of the expression of a return statement. |
| 4722 * | 4720 * |
| 4723 * This will be used for inferring a block bodied lambda, if no context | 4721 * This will be used for inferring a block bodied lambda, if no context |
| 4724 * type was available. | 4722 * type was available. |
| 4725 */ | 4723 */ |
| 4726 void addReturnOrYieldType(DartType type) { | 4724 void addReturnOrYieldType(DartType type) { |
| 4727 if (_returnStack.isEmpty) { | 4725 if (_returnStack.isEmpty) { |
| 4728 return; | 4726 return; |
| 4729 } | 4727 } |
| 4730 DartType inferred = _inferredReturn.last; | 4728 DartType context = _returnStack.last; |
| 4731 inferred = _typeSystem.getLeastUpperBound(_typeProvider, type, inferred); | 4729 if (context is! FutureUnionType) { |
| 4732 _inferredReturn[_inferredReturn.length - 1] = inferred; | 4730 DartType inferred = _inferredReturn.last; |
| 4731 inferred = _typeSystem.getLeastUpperBound(_typeProvider, type, inferred); |
| 4732 _inferredReturn[_inferredReturn.length - 1] = inferred; |
| 4733 } |
| 4733 } | 4734 } |
| 4734 | 4735 |
| 4735 /** | 4736 /** |
| 4736 * Match type [t1] against type [t2] as follows. | 4737 * Match type [t1] against type [t2] as follows. |
| 4737 * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype | 4738 * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype |
| 4738 * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>` | 4739 * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>` |
| 4739 * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'` | 4740 * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'` |
| 4740 * to derive a concrete instantation for I of the form `<T0, ..., Tn>`, | 4741 * to derive a concrete instantation for I of the form `<T0, ..., Tn>`, |
| 4741 * such that `I<T0, .., Tn> <: t2` | 4742 * such that `I<T0, .., Tn> <: t2` |
| 4742 */ | 4743 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4759 } | 4760 } |
| 4760 } else { | 4761 } else { |
| 4761 assert(false); | 4762 assert(false); |
| 4762 } | 4763 } |
| 4763 } | 4764 } |
| 4764 | 4765 |
| 4765 /** | 4766 /** |
| 4766 * Push a block function body's return type onto the return stack. | 4767 * Push a block function body's return type onto the return stack. |
| 4767 */ | 4768 */ |
| 4768 void pushReturnContext(BlockFunctionBody node) { | 4769 void pushReturnContext(BlockFunctionBody node) { |
| 4769 DartType returnType = getType(node); | 4770 _returnStack.add(getContext(node)); |
| 4770 _returnStack.add(returnType); | |
| 4771 _inferredReturn.add(BottomTypeImpl.instance); | 4771 _inferredReturn.add(BottomTypeImpl.instance); |
| 4772 } | 4772 } |
| 4773 | 4773 |
| 4774 /** | 4774 /** |
| 4775 * Place an info node into the error stream indicating that a | 4775 * Place an info node into the error stream indicating that a |
| 4776 * [type] has been inferred as the type of [node]. | 4776 * [type] has been inferred as the type of [node]. |
| 4777 */ | 4777 */ |
| 4778 void recordInference(Expression node, DartType type) { | 4778 void recordInference(Expression node, DartType type) { |
| 4779 if (!_inferenceHints) { | 4779 if (!_inferenceHints) { |
| 4780 return; | 4780 return; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4902 } | 4902 } |
| 4903 | 4903 |
| 4904 /** | 4904 /** |
| 4905 * Clear the type information assocated with [node]. | 4905 * Clear the type information assocated with [node]. |
| 4906 */ | 4906 */ |
| 4907 static void clearType(AstNode node) { | 4907 static void clearType(AstNode node) { |
| 4908 node?.setProperty(_typeProperty, null); | 4908 node?.setProperty(_typeProperty, null); |
| 4909 } | 4909 } |
| 4910 | 4910 |
| 4911 /** | 4911 /** |
| 4912 * Look for a single contextual type attached to [node], and returns the type |
| 4913 * if found, otherwise null. |
| 4914 * |
| 4915 * If [node] has a contextual union type like `T | Future<T>` this will |
| 4916 * simplify it to only return `T`. If the caller can handle a union type, |
| 4917 * [getContext] should be used instead. |
| 4918 */ |
| 4919 static DartType getType(AstNode node) { |
| 4920 DartType t = getContext(node); |
| 4921 if (t is FutureUnionType) { |
| 4922 return t.type; |
| 4923 } |
| 4924 return t; |
| 4925 } |
| 4926 |
| 4927 /** |
| 4912 * Look for contextual type information attached to [node]. Returns | 4928 * Look for contextual type information attached to [node]. Returns |
| 4913 * the type if found, otherwise null. | 4929 * the type if found, otherwise null. |
| 4930 * |
| 4931 * If [node] has a contextual union type like `T | Future<T>` this will be |
| 4932 * returned. You can use [getType] if you prefer to only get the `T`. |
| 4914 */ | 4933 */ |
| 4915 static DartType getType(AstNode node) => node?.getProperty(_typeProperty); | 4934 static DartType getContext(AstNode node) => node?.getProperty(_typeProperty); |
| 4935 |
| 4936 /** |
| 4937 * Like [getContext] but expands a union type into a list of types. |
| 4938 */ |
| 4939 static Iterable<DartType> getTypes(AstNode node) { |
| 4940 DartType t = getContext(node); |
| 4941 if (t == null) { |
| 4942 return DartType.EMPTY_LIST; |
| 4943 } |
| 4944 if (t is FutureUnionType) { |
| 4945 return t.types; |
| 4946 } |
| 4947 return <DartType>[t]; |
| 4948 } |
| 4916 | 4949 |
| 4917 /** | 4950 /** |
| 4918 * Attach contextual type information [type] to [node] for use during | 4951 * Attach contextual type information [type] to [node] for use during |
| 4919 * inference. | 4952 * inference. |
| 4920 */ | 4953 */ |
| 4921 static void setType(AstNode node, DartType type) { | 4954 static void setType(AstNode node, DartType type) { |
| 4922 // TODO(jmesserly): this sets the type even when it's dynamic. | |
| 4923 // Can we skip that? | |
| 4924 node?.setProperty(_typeProperty, type); | 4955 node?.setProperty(_typeProperty, type); |
| 4925 } | 4956 } |
| 4926 | 4957 |
| 4927 /** | 4958 /** |
| 4928 * Attach contextual type information [type] to [node] for use during | 4959 * Attach contextual type information [type] to [node] for use during |
| 4929 * inference. | 4960 * inference. |
| 4930 */ | 4961 */ |
| 4931 static void setTypeFromNode(AstNode innerNode, AstNode outerNode) { | 4962 static void setTypeFromNode(AstNode innerNode, AstNode outerNode) { |
| 4932 setType(innerNode, getType(outerNode)); | 4963 setType(innerNode, getContext(outerNode)); |
| 4933 } | 4964 } |
| 4934 } | 4965 } |
| 4935 | 4966 |
| 4936 /** | 4967 /** |
| 4937 * This enum holds one of four states of a field initialization state through a
constructor | 4968 * This enum holds one of four states of a field initialization state through a
constructor |
| 4938 * signature, not initialized, initialized in the field declaration, initialized
in the field | 4969 * signature, not initialized, initialized in the field declaration, initialized
in the field |
| 4939 * formal, and finally, initialized in the initializers list. | 4970 * formal, and finally, initialized in the initializers list. |
| 4940 */ | 4971 */ |
| 4941 class INIT_STATE extends Enum<INIT_STATE> { | 4972 class INIT_STATE extends Enum<INIT_STATE> { |
| 4942 static const INIT_STATE NOT_INIT = const INIT_STATE('NOT_INIT', 0); | 4973 static const INIT_STATE NOT_INIT = const INIT_STATE('NOT_INIT', 0); |
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6006 node.rightHandSide, node.leftHandSide.staticType); | 6037 node.rightHandSide, node.leftHandSide.staticType); |
| 6007 } | 6038 } |
| 6008 node.rightHandSide?.accept(this); | 6039 node.rightHandSide?.accept(this); |
| 6009 node.accept(elementResolver); | 6040 node.accept(elementResolver); |
| 6010 node.accept(typeAnalyzer); | 6041 node.accept(typeAnalyzer); |
| 6011 return null; | 6042 return null; |
| 6012 } | 6043 } |
| 6013 | 6044 |
| 6014 @override | 6045 @override |
| 6015 Object visitAwaitExpression(AwaitExpression node) { | 6046 Object visitAwaitExpression(AwaitExpression node) { |
| 6016 // TODO(leafp): Handle the implicit union type here | 6047 DartType contextType = InferenceContext.getContext(node); |
| 6017 // https://github.com/dart-lang/sdk/issues/25322 | |
| 6018 DartType contextType = InferenceContext.getType(node); | |
| 6019 if (contextType != null) { | 6048 if (contextType != null) { |
| 6020 InterfaceType futureT = typeProvider.futureType | 6049 var futureUnion = |
| 6021 .instantiate([contextType.flattenFutures(typeSystem)]); | 6050 FutureUnionType.from(contextType, typeProvider, typeSystem); |
| 6022 InferenceContext.setType(node.expression, futureT); | 6051 InferenceContext.setType(node.expression, futureUnion); |
| 6023 } | 6052 } |
| 6024 return super.visitAwaitExpression(node); | 6053 return super.visitAwaitExpression(node); |
| 6025 } | 6054 } |
| 6026 | 6055 |
| 6027 @override | 6056 @override |
| 6028 Object visitBinaryExpression(BinaryExpression node) { | 6057 Object visitBinaryExpression(BinaryExpression node) { |
| 6029 TokenType operatorType = node.operator.type; | 6058 TokenType operatorType = node.operator.type; |
| 6030 Expression leftOperand = node.leftOperand; | 6059 Expression leftOperand = node.leftOperand; |
| 6031 Expression rightOperand = node.rightOperand; | 6060 Expression rightOperand = node.rightOperand; |
| 6032 if (operatorType == TokenType.AMPERSAND_AMPERSAND) { | 6061 if (operatorType == TokenType.AMPERSAND_AMPERSAND) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6066 } else { | 6095 } else { |
| 6067 // TODO(leafp): Do downwards inference using the declared type | 6096 // TODO(leafp): Do downwards inference using the declared type |
| 6068 // of the binary operator for other cases. | 6097 // of the binary operator for other cases. |
| 6069 if (operatorType == TokenType.QUESTION_QUESTION) { | 6098 if (operatorType == TokenType.QUESTION_QUESTION) { |
| 6070 InferenceContext.setTypeFromNode(leftOperand, node); | 6099 InferenceContext.setTypeFromNode(leftOperand, node); |
| 6071 } | 6100 } |
| 6072 leftOperand?.accept(this); | 6101 leftOperand?.accept(this); |
| 6073 if (operatorType == TokenType.QUESTION_QUESTION) { | 6102 if (operatorType == TokenType.QUESTION_QUESTION) { |
| 6074 // Set the right side, either from the context, or using the information | 6103 // Set the right side, either from the context, or using the information |
| 6075 // from the left side if it is more precise. | 6104 // from the left side if it is more precise. |
| 6076 DartType contextType = InferenceContext.getType(node); | 6105 DartType contextType = InferenceContext.getContext(node); |
| 6077 DartType leftType = leftOperand?.staticType; | 6106 DartType leftType = leftOperand?.staticType; |
| 6078 if (contextType == null || contextType.isDynamic) { | 6107 if (contextType == null || contextType.isDynamic) { |
| 6079 contextType = leftType; | 6108 contextType = leftType; |
| 6080 } | 6109 } |
| 6081 InferenceContext.setType(rightOperand, contextType); | 6110 InferenceContext.setType(rightOperand, contextType); |
| 6082 } | 6111 } |
| 6083 rightOperand?.accept(this); | 6112 rightOperand?.accept(this); |
| 6084 } | 6113 } |
| 6085 node.accept(elementResolver); | 6114 node.accept(elementResolver); |
| 6086 node.accept(typeAnalyzer); | 6115 node.accept(typeAnalyzer); |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6544 _currentFunctionBody = node.body; | 6573 _currentFunctionBody = node.body; |
| 6545 _enclosingFunction = node.element; | 6574 _enclosingFunction = node.element; |
| 6546 _overrideManager.enterScope(); | 6575 _overrideManager.enterScope(); |
| 6547 try { | 6576 try { |
| 6548 DartType functionType = InferenceContext.getType(node); | 6577 DartType functionType = InferenceContext.getType(node); |
| 6549 if (functionType is FunctionType) { | 6578 if (functionType is FunctionType) { |
| 6550 functionType = | 6579 functionType = |
| 6551 matchFunctionTypeParameters(node.typeParameters, functionType); | 6580 matchFunctionTypeParameters(node.typeParameters, functionType); |
| 6552 if (functionType is FunctionType) { | 6581 if (functionType is FunctionType) { |
| 6553 _inferFormalParameterList(node.parameters, functionType); | 6582 _inferFormalParameterList(node.parameters, functionType); |
| 6554 DartType returnType = | 6583 |
| 6555 _computeReturnOrYieldType(functionType.returnType); | 6584 DartType returnType; |
| 6585 if (_isFutureThenLambda(node)) { |
| 6586 var futureThenType = |
| 6587 InferenceContext.getContext(node.parent) as FunctionType; |
| 6588 |
| 6589 // Pretend the return type of Future<T>.then<S> first parameter is |
| 6590 // |
| 6591 // T -> (S | Future<S>) |
| 6592 // |
| 6593 // We can't represent this in Dart so we populate it here during |
| 6594 // inference. |
| 6595 returnType = FutureUnionType.from( |
| 6596 futureThenType.returnType, typeProvider, typeSystem); |
| 6597 } else { |
| 6598 returnType = _computeReturnOrYieldType(functionType.returnType); |
| 6599 } |
| 6600 |
| 6556 InferenceContext.setType(node.body, returnType); | 6601 InferenceContext.setType(node.body, returnType); |
| 6557 } | 6602 } |
| 6558 } | 6603 } |
| 6559 super.visitFunctionExpression(node); | 6604 super.visitFunctionExpression(node); |
| 6560 } finally { | 6605 } finally { |
| 6561 _overrideManager.exitScope(); | 6606 _overrideManager.exitScope(); |
| 6562 } | 6607 } |
| 6563 } finally { | 6608 } finally { |
| 6564 _currentFunctionBody = outerFunctionBody; | 6609 _currentFunctionBody = outerFunctionBody; |
| 6565 _enclosingFunction = outerFunction; | 6610 _enclosingFunction = outerFunction; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6661 perBranchOverrides.add(elseOverrides); | 6706 perBranchOverrides.add(elseOverrides); |
| 6662 _overrideManager.mergeOverrides(perBranchOverrides); | 6707 _overrideManager.mergeOverrides(perBranchOverrides); |
| 6663 } | 6708 } |
| 6664 return null; | 6709 return null; |
| 6665 } | 6710 } |
| 6666 | 6711 |
| 6667 @override | 6712 @override |
| 6668 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 6713 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 6669 TypeName classTypeName = node.constructorName.type; | 6714 TypeName classTypeName = node.constructorName.type; |
| 6670 if (classTypeName.typeArguments == null) { | 6715 if (classTypeName.typeArguments == null) { |
| 6671 DartType contextType = InferenceContext.getType(node); | 6716 // Given a union of context types ` T0 | T1 | ... | Tn`, find the first |
| 6672 if (contextType is InterfaceType && | 6717 // valid instantiation `new C<Ti>`, if it exists. |
| 6673 contextType.typeArguments != null && | 6718 // TODO(jmesserly): if we support union types for real, `new C<Ti | Tj>` |
| 6674 contextType.typeArguments.length > 0) { | 6719 // will become a valid possibility. Right now the only allowed union is |
| 6675 // TODO(jmesserly): for generic methods we use the | 6720 // `T | Future<T>` so we can take a simple approach. |
| 6676 // StrongTypeSystemImpl.inferGenericFunctionCall, which appears to | 6721 for (var contextType in InferenceContext.getTypes(node)) { |
| 6677 // be a tad more powerful than matchTypes. | 6722 if (contextType is InterfaceType && |
| 6678 // | 6723 contextType.typeArguments != null && |
| 6679 // For example it can infer this case: | 6724 contextType.typeArguments.isNotEmpty) { |
| 6680 // | 6725 // TODO(jmesserly): for generic methods we use the |
| 6681 // class E<S, T> extends A<C<S>, T> { ... } | 6726 // StrongTypeSystemImpl.inferGenericFunctionCall, which appears to |
| 6682 // A<C<int>, String> a0 = /*infer<int, String>*/new E("hello"); | 6727 // be a tad more powerful than matchTypes. |
| 6683 // | 6728 // |
| 6684 // See _inferArgumentTypesFromContext in this file for use of it. | 6729 // For example it can infer this case: |
| 6685 List<DartType> targs = | 6730 // |
| 6686 inferenceContext.matchTypes(classTypeName.type, contextType); | 6731 // class E<S, T> extends A<C<S>, T> { ... } |
| 6687 if (targs != null && targs.any((t) => !t.isDynamic)) { | 6732 // A<C<int>, String> a0 = /*infer<int, String>*/new E("hello"); |
| 6688 ClassElement classElement = classTypeName.type.element; | 6733 // |
| 6689 InterfaceType rawType = classElement.type; | 6734 // See _inferArgumentTypesFromContext in this file for use of it. |
| 6690 InterfaceType fullType = | 6735 List<DartType> targs = |
| 6691 rawType.substitute2(targs, rawType.typeArguments); | 6736 inferenceContext.matchTypes(classTypeName.type, contextType); |
| 6692 // The element resolver uses the type on the constructor name, so | 6737 if (targs != null && targs.any((t) => !t.isDynamic)) { |
| 6693 // infer it first | 6738 ClassElement classElement = classTypeName.type.element; |
| 6694 typeAnalyzer.inferConstructorName(node.constructorName, fullType); | 6739 InterfaceType rawType = classElement.type; |
| 6740 InterfaceType fullType = |
| 6741 rawType.substitute2(targs, rawType.typeArguments); |
| 6742 // The element resolver uses the type on the constructor name, so |
| 6743 // infer it first |
| 6744 typeAnalyzer.inferConstructorName(node.constructorName, fullType); |
| 6745 break; |
| 6746 } |
| 6695 } | 6747 } |
| 6696 } | 6748 } |
| 6697 } | 6749 } |
| 6698 node.constructorName?.accept(this); | 6750 node.constructorName?.accept(this); |
| 6699 FunctionType constructorType = node.constructorName.staticElement?.type; | 6751 FunctionType constructorType = node.constructorName.staticElement?.type; |
| 6700 if (constructorType != null) { | 6752 if (constructorType != null) { |
| 6701 InferenceContext.setType(node.argumentList, constructorType); | 6753 InferenceContext.setType(node.argumentList, constructorType); |
| 6702 } | 6754 } |
| 6703 node.argumentList?.accept(this); | 6755 node.argumentList?.accept(this); |
| 6704 node.accept(elementResolver); | 6756 node.accept(elementResolver); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6798 node.typeArguments?.accept(this); | 6850 node.typeArguments?.accept(this); |
| 6799 node.accept(elementResolver); | 6851 node.accept(elementResolver); |
| 6800 _inferArgumentTypesFromContext(node); | 6852 _inferArgumentTypesFromContext(node); |
| 6801 node.argumentList?.accept(this); | 6853 node.argumentList?.accept(this); |
| 6802 node.accept(typeAnalyzer); | 6854 node.accept(typeAnalyzer); |
| 6803 return null; | 6855 return null; |
| 6804 } | 6856 } |
| 6805 | 6857 |
| 6806 @override | 6858 @override |
| 6807 Object visitNamedExpression(NamedExpression node) { | 6859 Object visitNamedExpression(NamedExpression node) { |
| 6808 InferenceContext.setType(node.expression, InferenceContext.getType(node)); | 6860 InferenceContext.setTypeFromNode(node.expression, node); |
| 6809 return super.visitNamedExpression(node); | 6861 return super.visitNamedExpression(node); |
| 6810 } | 6862 } |
| 6811 | 6863 |
| 6812 @override | 6864 @override |
| 6813 Object visitNode(AstNode node) { | 6865 Object visitNode(AstNode node) { |
| 6814 node.visitChildren(this); | 6866 node.visitChildren(this); |
| 6815 node.accept(elementResolver); | 6867 node.accept(elementResolver); |
| 6816 node.accept(typeAnalyzer); | 6868 node.accept(typeAnalyzer); |
| 6817 return null; | 6869 return null; |
| 6818 } | 6870 } |
| 6819 | 6871 |
| 6820 @override | 6872 @override |
| 6821 Object visitParenthesizedExpression(ParenthesizedExpression node) { | 6873 Object visitParenthesizedExpression(ParenthesizedExpression node) { |
| 6822 InferenceContext.setType(node.expression, InferenceContext.getType(node)); | 6874 InferenceContext.setTypeFromNode(node.expression, node); |
| 6823 return super.visitParenthesizedExpression(node); | 6875 return super.visitParenthesizedExpression(node); |
| 6824 } | 6876 } |
| 6825 | 6877 |
| 6826 @override | 6878 @override |
| 6827 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 6879 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 6828 // | 6880 // |
| 6829 // We visit the prefix, but do not visit the identifier because it needs to | 6881 // We visit the prefix, but do not visit the identifier because it needs to |
| 6830 // be visited in the context of the prefix. | 6882 // be visited in the context of the prefix. |
| 6831 // | 6883 // |
| 6832 node.prefix?.accept(this); | 6884 node.prefix?.accept(this); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6930 _overrideManager.applyOverrides(overrides); | 6982 _overrideManager.applyOverrides(overrides); |
| 6931 } | 6983 } |
| 6932 return null; | 6984 return null; |
| 6933 } | 6985 } |
| 6934 | 6986 |
| 6935 @override | 6987 @override |
| 6936 Object visitTypeName(TypeName node) => null; | 6988 Object visitTypeName(TypeName node) => null; |
| 6937 | 6989 |
| 6938 @override | 6990 @override |
| 6939 Object visitVariableDeclaration(VariableDeclaration node) { | 6991 Object visitVariableDeclaration(VariableDeclaration node) { |
| 6940 InferenceContext.setType(node.initializer, InferenceContext.getType(node)); | 6992 InferenceContext.setTypeFromNode(node.initializer, node); |
| 6941 super.visitVariableDeclaration(node); | 6993 super.visitVariableDeclaration(node); |
| 6942 VariableElement element = node.element; | 6994 VariableElement element = node.element; |
| 6943 if (element.initializer != null && node.initializer != null) { | 6995 if (element.initializer != null && node.initializer != null) { |
| 6944 (element.initializer as FunctionElementImpl).returnType = | 6996 (element.initializer as FunctionElementImpl).returnType = |
| 6945 node.initializer.staticType; | 6997 node.initializer.staticType; |
| 6946 } | 6998 } |
| 6947 // Note: in addition to cloning the initializers for const variables, we | 6999 // Note: in addition to cloning the initializers for const variables, we |
| 6948 // have to clone the initializers for non-static final fields (because if | 7000 // have to clone the initializers for non-static final fields (because if |
| 6949 // they occur in a class with a const constructor, they will be needed to | 7001 // they occur in a class with a const constructor, they will be needed to |
| 6950 // evaluate the const constructor). | 7002 // evaluate the const constructor). |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7074 * cannot be computed from the declared return type, return null. | 7126 * cannot be computed from the declared return type, return null. |
| 7075 */ | 7127 */ |
| 7076 DartType _computeReturnOrYieldType(DartType declaredType) { | 7128 DartType _computeReturnOrYieldType(DartType declaredType) { |
| 7077 bool isGenerator = _enclosingFunction.isGenerator; | 7129 bool isGenerator = _enclosingFunction.isGenerator; |
| 7078 bool isAsynchronous = _enclosingFunction.isAsynchronous; | 7130 bool isAsynchronous = _enclosingFunction.isAsynchronous; |
| 7079 | 7131 |
| 7080 // Ordinary functions just return their declared types. | 7132 // Ordinary functions just return their declared types. |
| 7081 if (!isGenerator && !isAsynchronous) { | 7133 if (!isGenerator && !isAsynchronous) { |
| 7082 return declaredType; | 7134 return declaredType; |
| 7083 } | 7135 } |
| 7084 if (isGenerator) { | 7136 if (declaredType is InterfaceType) { |
| 7085 if (declaredType is! InterfaceType) { | 7137 if (isGenerator) { |
| 7086 return null; | 7138 // If it's sync* we expect Iterable<T> |
| 7139 // If it's async* we expect Stream<T> |
| 7140 InterfaceType rawType = isAsynchronous |
| 7141 ? typeProvider.streamDynamicType |
| 7142 : typeProvider.iterableDynamicType; |
| 7143 // Match the types to instantiate the type arguments if possible |
| 7144 List<DartType> typeArgs = |
| 7145 inferenceContext.matchTypes(rawType, declaredType); |
| 7146 return (typeArgs?.length == 1) ? typeArgs[0] : null; |
| 7087 } | 7147 } |
| 7088 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> | 7148 // async functions expect `Future<T> | T` |
| 7089 InterfaceType rawType = isAsynchronous | 7149 return new FutureUnionType(declaredType, typeProvider, typeSystem); |
| 7090 ? typeProvider.streamDynamicType | |
| 7091 : typeProvider.iterableDynamicType; | |
| 7092 // Match the types to instantiate the type arguments if possible | |
| 7093 List<DartType> typeArgs = | |
| 7094 inferenceContext.matchTypes(rawType, declaredType); | |
| 7095 return (typeArgs?.length == 1) ? typeArgs[0] : null; | |
| 7096 } | 7150 } |
| 7097 // Must be asynchronous to reach here, so strip off any layers of Future | 7151 return declaredType; |
| 7098 return declaredType.flattenFutures(typeSystem); | |
| 7099 } | 7152 } |
| 7100 | 7153 |
| 7101 /** | 7154 /** |
| 7102 * The given expression is the expression used to compute the iterator for a | 7155 * The given expression is the expression used to compute the iterator for a |
| 7103 * for-each statement. Attempt to compute the type of objects that will be | 7156 * for-each statement. Attempt to compute the type of objects that will be |
| 7104 * assigned to the loop variable and return that type. Return `null` if the | 7157 * assigned to the loop variable and return that type. Return `null` if the |
| 7105 * type could not be determined. The [iteratorExpression] is the expression | 7158 * type could not be determined. The [iteratorExpression] is the expression |
| 7106 * that will return the Iterable being iterated over. | 7159 * that will return the Iterable being iterated over. |
| 7107 */ | 7160 */ |
| 7108 DartType _getIteratorElementType(Expression iteratorExpression) { | 7161 DartType _getIteratorElementType(Expression iteratorExpression) { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7333 // | 7386 // |
| 7334 // Unsound to assume that [x = "hello";] never executed after the | 7387 // Unsound to assume that [x = "hello";] never executed after the |
| 7335 // if-statement. Of course, a dead-code analysis could point out that | 7388 // if-statement. Of course, a dead-code analysis could point out that |
| 7336 // [return] here is dead. | 7389 // [return] here is dead. |
| 7337 return _isAbruptTerminationStatement(statements[size - 1]); | 7390 return _isAbruptTerminationStatement(statements[size - 1]); |
| 7338 } | 7391 } |
| 7339 return false; | 7392 return false; |
| 7340 } | 7393 } |
| 7341 | 7394 |
| 7342 /** | 7395 /** |
| 7396 * Returns true if this expression is being passed to `Future.then`. |
| 7397 * |
| 7398 * If so we will apply special typing rules in strong mode, to handle the |
| 7399 * implicit union of `S | Future<S>` |
| 7400 */ |
| 7401 bool _isFutureThenLambda(FunctionExpression node) { |
| 7402 Element element = node.staticParameterElement?.enclosingElement; |
| 7403 return element is MethodElement && |
| 7404 element.name == 'then' && |
| 7405 element.enclosingElement.type.isDartAsyncFuture; |
| 7406 } |
| 7407 |
| 7408 /** |
| 7343 * Return `true` if the given variable is accessed within a closure in the giv
en | 7409 * Return `true` if the given variable is accessed within a closure in the giv
en |
| 7344 * [AstNode] and also mutated somewhere in variable scope. This information is
only | 7410 * [AstNode] and also mutated somewhere in variable scope. This information is
only |
| 7345 * available for local variables (including parameters). | 7411 * available for local variables (including parameters). |
| 7346 * | 7412 * |
| 7347 * @param variable the variable to check | 7413 * @param variable the variable to check |
| 7348 * @param target the [AstNode] to check within | 7414 * @param target the [AstNode] to check within |
| 7349 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode | 7415 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode |
| 7350 */ | 7416 */ |
| 7351 bool _isVariableAccessedInClosure(Element variable, AstNode target) { | 7417 bool _isVariableAccessedInClosure(Element variable, AstNode target) { |
| 7352 _ResolverVisitor_isVariableAccessedInClosure visitor = | 7418 _ResolverVisitor_isVariableAccessedInClosure visitor = |
| (...skipping 3685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11038 return null; | 11104 return null; |
| 11039 } | 11105 } |
| 11040 if (identical(node.staticElement, variable)) { | 11106 if (identical(node.staticElement, variable)) { |
| 11041 if (node.inSetterContext()) { | 11107 if (node.inSetterContext()) { |
| 11042 result = true; | 11108 result = true; |
| 11043 } | 11109 } |
| 11044 } | 11110 } |
| 11045 return null; | 11111 return null; |
| 11046 } | 11112 } |
| 11047 } | 11113 } |
| OLD | NEW |