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, |