| Index: pkg/analyzer/lib/src/generated/static_type_analyzer.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
|
| index fa82560e055276642182e1a99c6336ffe21b0717..bc5c56cf666053fae9ad713dc238e30069f0e660 100644
|
| --- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
|
| +++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
|
| @@ -17,6 +17,7 @@ import 'package:analyzer/src/dart/element/type.dart';
|
| import 'package:analyzer/src/generated/java_engine.dart';
|
| import 'package:analyzer/src/generated/resolver.dart';
|
| import 'package:analyzer/src/generated/utilities_dart.dart';
|
| +import 'package:analyzer/src/task/strong/checker.dart' show getDefiniteType;
|
|
|
| /**
|
| * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
|
| @@ -495,44 +496,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| }
|
|
|
| /**
|
| - * Infers the return type of a local function, either a lambda or
|
| - * (in strong mode) a local function declaration.
|
| - */
|
| - void _inferLocalFunctionReturnType(FunctionExpression node) {
|
| - bool recordInference = false;
|
| - ExecutableElementImpl functionElement =
|
| - node.element as ExecutableElementImpl;
|
| -
|
| - FunctionBody body = node.body;
|
| - DartType computedType;
|
| - if (body is ExpressionFunctionBody) {
|
| - computedType = _getStaticType(body.expression);
|
| - } else {
|
| - computedType = _dynamicType;
|
| - }
|
| -
|
| - // If we had a better type from the function body, use it.
|
| - //
|
| - // This helps in a few cases:
|
| - // * ExpressionFunctionBody, when the surrounding context had a better type.
|
| - // * BlockFunctionBody, if we inferred a type from yield/return.
|
| - // * we also normalize bottom to dynamic here.
|
| - if (_strongMode && (computedType.isBottom || computedType.isDynamic)) {
|
| - computedType = InferenceContext.getType(body) ?? _dynamicType;
|
| - recordInference = !computedType.isDynamic;
|
| - }
|
| -
|
| - computedType = _computeReturnTypeOfFunction(body, computedType);
|
| -
|
| - functionElement.returnType = computedType;
|
| - _recordPropagatedTypeOfFunction(functionElement, node.body);
|
| - _recordStaticType(node, functionElement.type);
|
| - if (recordInference) {
|
| - _resolver.inferenceContext.recordInference(node, functionElement.type);
|
| - }
|
| - }
|
| -
|
| - /**
|
| * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i>
|
| * has the form <i>e<sub>f</sub>(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>:
|
| * a<sub>n+1</sub>, …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is
|
| @@ -1475,8 +1438,8 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| */
|
| void _analyzeLeastUpperBound(
|
| Expression node, Expression expr1, Expression expr2) {
|
| - DartType staticType1 = _getStaticType(expr1);
|
| - DartType staticType2 = _getStaticType(expr2);
|
| + DartType staticType1 = _getDefiniteType(expr1);
|
| + DartType staticType2 = _getDefiniteType(expr2);
|
| if (staticType1 == null) {
|
| // TODO(brianwilkerson) Determine whether this can still happen.
|
| staticType1 = _dynamicType;
|
| @@ -1697,6 +1660,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| visitedClasses.remove(element);
|
| }
|
| }
|
| +
|
| if (type is InterfaceType) {
|
| _find(type);
|
| }
|
| @@ -1704,6 +1668,17 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| }
|
|
|
| /**
|
| + * Gets the definite type of expression, which can be used in cases where
|
| + * the most precise type is desired, for example computing the least upper
|
| + * bound.
|
| + *
|
| + * See [getDefiniteType] for more information. Without strong mode, this is
|
| + * equivalent to [_getStaticType].
|
| + */
|
| + DartType _getDefiniteType(Expression expr) =>
|
| + getDefiniteType(expr, _typeSystem, _typeProvider);
|
| +
|
| + /**
|
| * If the given element name can be mapped to the name of a class defined within the given
|
| * library, return the type specified by the argument.
|
| *
|
| @@ -2032,6 +2007,44 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| }
|
|
|
| /**
|
| + * Infers the return type of a local function, either a lambda or
|
| + * (in strong mode) a local function declaration.
|
| + */
|
| + void _inferLocalFunctionReturnType(FunctionExpression node) {
|
| + bool recordInference = false;
|
| + ExecutableElementImpl functionElement =
|
| + node.element as ExecutableElementImpl;
|
| +
|
| + FunctionBody body = node.body;
|
| + DartType computedType;
|
| + if (body is ExpressionFunctionBody) {
|
| + computedType = _getStaticType(body.expression);
|
| + } else {
|
| + computedType = _dynamicType;
|
| + }
|
| +
|
| + // If we had a better type from the function body, use it.
|
| + //
|
| + // This helps in a few cases:
|
| + // * ExpressionFunctionBody, when the surrounding context had a better type.
|
| + // * BlockFunctionBody, if we inferred a type from yield/return.
|
| + // * we also normalize bottom to dynamic here.
|
| + if (_strongMode && (computedType.isBottom || computedType.isDynamic)) {
|
| + computedType = InferenceContext.getType(body) ?? _dynamicType;
|
| + recordInference = !computedType.isDynamic;
|
| + }
|
| +
|
| + computedType = _computeReturnTypeOfFunction(body, computedType);
|
| +
|
| + functionElement.returnType = computedType;
|
| + _recordPropagatedTypeOfFunction(functionElement, node.body);
|
| + _recordStaticType(node, functionElement.type);
|
| + if (recordInference) {
|
| + _resolver.inferenceContext.recordInference(node, functionElement.type);
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Given a local variable declaration and its initializer, attempt to infer
|
| * a type for the local variable declaration based on the initializer.
|
| * Inference is only done if an explicit type is not present, and if
|
|
|