| 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 a2aeae15c7741c74e7444e1ef09841ccf790c371..8efa4bee5bbfbb827afe5f364d23899a73995a0c 100644
|
| --- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
|
| +++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
|
| @@ -106,9 +106,10 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| void inferConstructorName(ConstructorName node, InterfaceType type) {
|
| if (_strongMode) {
|
| node.type.type = type;
|
| - _resolver.inferenceContext.recordInference(node.parent, type);
|
| + if (type != _typeSystem.instantiateToBounds(type.element.type)) {
|
| + _resolver.inferenceContext.recordInference(node.parent, type);
|
| + }
|
| }
|
| - return;
|
| }
|
|
|
| /**
|
| @@ -628,24 +629,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| // If there are no type arguments and we are in strong mode, try to infer
|
| // some arguments.
|
| if (_strongMode) {
|
| - DartType contextType = InferenceContext.getType(node);
|
| -
|
| - // Use both downwards and upwards information to infer the type.
|
| - var ts = _typeSystem as StrongTypeSystemImpl;
|
| - var elementTypes = node.elements
|
| - .map((e) => e.staticType)
|
| - .where((t) => t != null)
|
| - .toList();
|
| - var listTypeParam = _typeProvider.listType.typeParameters[0].type;
|
| -
|
| - DartType inferred = ts.inferGenericFunctionCall(
|
| - _typeProvider.listType,
|
| - new List.filled(elementTypes.length, listTypeParam),
|
| - elementTypes,
|
| - _typeProvider.listType,
|
| - contextType,
|
| - errorReporter: _resolver.errorReporter,
|
| - errorNode: node);
|
| + DartType inferred = inferListType(node);
|
|
|
| if (inferred != listDynamicType) {
|
| // TODO(jmesserly): this results in an "inferred" message even when we
|
| @@ -663,6 +647,43 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| return null;
|
| }
|
|
|
| + DartType inferListType(ListLiteral node, {bool downwards: false}) {
|
| + DartType contextType = InferenceContext.getContext(node);
|
| +
|
| + var ts = _typeSystem as StrongTypeSystemImpl;
|
| + List<DartType> elementTypes;
|
| + List<ParameterElement> parameters;
|
| +
|
| + if (downwards) {
|
| + if (contextType == null) {
|
| + return null;
|
| + }
|
| +
|
| + elementTypes = [];
|
| + parameters = [];
|
| + } else {
|
| + // Also use upwards information to infer the type.
|
| + elementTypes = node.elements
|
| + .map((e) => e.staticType)
|
| + .where((t) => t != null)
|
| + .toList();
|
| + var listTypeParam = _typeProvider.listType.typeParameters[0].type;
|
| + var syntheticParamElement = new ParameterElementImpl.synthetic(
|
| + 'element', listTypeParam, ParameterKind.POSITIONAL);
|
| + parameters = new List.filled(elementTypes.length, syntheticParamElement);
|
| + }
|
| + DartType inferred = ts.inferGenericFunctionOrType/*<InterfaceType>*/(
|
| + _typeProvider.listType,
|
| + parameters,
|
| + elementTypes,
|
| + _typeProvider.listType,
|
| + contextType,
|
| + downwards: downwards,
|
| + errorReporter: _resolver.errorReporter,
|
| + errorNode: node);
|
| + return inferred;
|
| + }
|
| +
|
| /**
|
| * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
|
| * <i><b>const</b> <K, V> {k<sub>1</sub>:e<sub>1</sub>, …,
|
| @@ -707,26 +728,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| // If we have no explicit type arguments, and we are in strong mode
|
| // then try to infer type arguments.
|
| if (_strongMode) {
|
| - DartType contextType = InferenceContext.getType(node);
|
| -
|
| - // Use both downwards and upwards information to infer the type.
|
| - var ts = _typeSystem as StrongTypeSystemImpl;
|
| - var keyTypes =
|
| - node.entries.map((e) => e.key.staticType).where((t) => t != null);
|
| - var valueTypes =
|
| - node.entries.map((e) => e.value.staticType).where((t) => t != null);
|
| - var keyTypeParam = _typeProvider.mapType.typeParameters[0].type;
|
| - var valueTypeParam = _typeProvider.mapType.typeParameters[1].type;
|
| -
|
| - DartType inferred = ts.inferGenericFunctionCall(
|
| - _typeProvider.mapType,
|
| - new List.filled(keyTypes.length, keyTypeParam, growable: true)
|
| - ..addAll(new List.filled(valueTypes.length, valueTypeParam)),
|
| - new List.from(keyTypes)..addAll(valueTypes),
|
| - _typeProvider.mapType,
|
| - contextType,
|
| - errorReporter: _resolver.errorReporter,
|
| - errorNode: node);
|
| + ParameterizedType inferred = inferMapType(node);
|
|
|
| if (inferred != mapDynamicType) {
|
| // TODO(jmesserly): this results in an "inferred" message even when we
|
| @@ -744,6 +746,47 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| return null;
|
| }
|
|
|
| + ParameterizedType inferMapType(MapLiteral node, {bool downwards: false}) {
|
| + DartType contextType = InferenceContext.getContext(node);
|
| +
|
| + List<DartType> elementTypes;
|
| + List<ParameterElement> parameters;
|
| + if (downwards) {
|
| + if (contextType == null) {
|
| + return null;
|
| + }
|
| + elementTypes = [];
|
| + parameters = [];
|
| + } else {
|
| + var keyTypes =
|
| + node.entries.map((e) => e.key.staticType).where((t) => t != null);
|
| + var valueTypes =
|
| + node.entries.map((e) => e.value.staticType).where((t) => t != null);
|
| + var keyTypeParam = _typeProvider.mapType.typeParameters[0].type;
|
| + var valueTypeParam = _typeProvider.mapType.typeParameters[1].type;
|
| + var syntheticKeyParameter = new ParameterElementImpl.synthetic(
|
| + 'key', keyTypeParam, ParameterKind.POSITIONAL);
|
| + var syntheticValueParameter = new ParameterElementImpl.synthetic(
|
| + 'value', valueTypeParam, ParameterKind.POSITIONAL);
|
| + parameters = new List.filled(keyTypes.length, syntheticKeyParameter,
|
| + growable: true)
|
| + ..addAll(new List.filled(valueTypes.length, syntheticValueParameter));
|
| + elementTypes = new List<DartType>.from(keyTypes)..addAll(valueTypes);
|
| + }
|
| +
|
| + // Use both downwards and upwards information to infer the type.
|
| + var ts = _typeSystem as StrongTypeSystemImpl;
|
| + ParameterizedType inferred = ts.inferGenericFunctionOrType(
|
| + _typeProvider.mapType,
|
| + parameters,
|
| + elementTypes,
|
| + _typeProvider.mapType,
|
| + contextType,
|
| + errorReporter: _resolver.errorReporter,
|
| + errorNode: node);
|
| + return inferred;
|
| + }
|
| +
|
| /**
|
| * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method invocation <i>i</i>
|
| * has the form <i>o.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
|
| @@ -1073,7 +1116,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| staticType = staticElement.type;
|
| }
|
| staticType = _inferGenericInstantiationFromContext(node, staticType);
|
| -
|
| if (!(_strongMode &&
|
| _inferObjectAccess(node, staticType, prefixedIdentifier))) {
|
| _recordStaticType(prefixedIdentifier, staticType);
|
| @@ -1204,7 +1246,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| // TODO(brianwilkerson) Report this internal error.
|
| }
|
| staticType = _inferGenericInstantiationFromContext(node, staticType);
|
| -
|
| if (!(_strongMode && _inferObjectAccess(node, staticType, propertyName))) {
|
| _recordStaticType(propertyName, staticType);
|
| _recordStaticType(node, staticType);
|
| @@ -1306,7 +1347,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| staticType = _dynamicType;
|
| }
|
| staticType = _inferGenericInstantiationFromContext(node, staticType);
|
| -
|
| _recordStaticType(node, staticType);
|
| // TODO(brianwilkerson) I think we want to repeat the logic above using the
|
| // propagated element to get another candidate for the propagated type.
|
| @@ -1582,7 +1622,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| * For example given the type `class C<T> { C(T arg); }`, the generic function
|
| * type is `<T>(T) -> C<T>`.
|
| */
|
| - FunctionType _constructorToGenericFunctionType(
|
| + FunctionType constructorToGenericFunctionType(
|
| ConstructorElement constructor) {
|
| // TODO(jmesserly): it may be worth making this available from the
|
| // constructor. It's nice if our inference code can operate uniformly on
|
| @@ -1620,7 +1660,11 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
|
|
| type = type.substitute2(freshTypeVars, typeVars);
|
|
|
| - var function = new FunctionElementImpl("", -1);
|
| + var name = cls.name;
|
| + if (constructor.name != null) {
|
| + name += '.' + constructor.name;
|
| + }
|
| + var function = new FunctionElementImpl(name, -1);
|
| function.isSynthetic = true;
|
| function.returnType = type.returnType;
|
| function.typeParameters = freshVarElements;
|
| @@ -1902,11 +1946,12 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| DartType _inferGenericInstantiationFromContext(AstNode node, DartType type) {
|
| if (_strongMode) {
|
| TypeSystem ts = _typeSystem;
|
| - DartType context = InferenceContext.getType(node);
|
| + var context = InferenceContext.getContext(node);
|
| if (context is FunctionType &&
|
| type is FunctionType &&
|
| ts is StrongTypeSystemImpl) {
|
| - return ts.inferFunctionTypeInstantiation(context, type);
|
| + return ts.inferFunctionTypeInstantiation(context, type,
|
| + errorReporter: _resolver.errorReporter, errorNode: node);
|
| }
|
| } else if (type is FunctionType) {
|
| // In Dart 1 mode we want to implicitly instantiate generic functions to
|
| @@ -1958,16 +2003,17 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| List<ParameterElement> rawParameters = ResolverVisitor
|
| .resolveArgumentsToParameters(argumentList, fnType.parameters, null);
|
|
|
| - List<DartType> paramTypes = <DartType>[];
|
| + List<ParameterElement> params = <ParameterElement>[];
|
| List<DartType> argTypes = <DartType>[];
|
| for (int i = 0, length = rawParameters.length; i < length; i++) {
|
| ParameterElement parameter = rawParameters[i];
|
| if (parameter != null) {
|
| - paramTypes.add(parameter.type);
|
| + params.add(parameter);
|
| argTypes.add(argumentList.arguments[i].staticType);
|
| }
|
| }
|
| - return ts.inferGenericFunctionCall(fnType, paramTypes, argTypes,
|
| +
|
| + return ts.inferGenericFunctionOrType(fnType, params, argTypes,
|
| fnType.returnType, InferenceContext.getContext(node),
|
| errorReporter: _resolver.errorReporter, errorNode: errorNode);
|
| }
|
| @@ -2003,8 +2049,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
|
| // Or look it up, instead of jumping backwards through the Member?
|
| var rawElement = (originalElement as ConstructorMember).baseElement;
|
|
|
| - FunctionType constructorType =
|
| - _constructorToGenericFunctionType(rawElement);
|
| + FunctionType constructorType = constructorToGenericFunctionType(rawElement);
|
|
|
| ArgumentList arguments = node.argumentList;
|
| FunctionType inferred = _inferGenericInvoke(node, constructorType,
|
|
|