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

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

Issue 2208953002: fix #25944, improve Future.then inference (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix based on comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/static_type_analyzer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library 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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/static_type_analyzer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698