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 4b96f41e8d0d841b4df240ef960c82290204eef4..52a7eafefd0e0d73f0dad121642c0a355aba73a2 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; |
} |
/** |
@@ -121,14 +122,17 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
FormalParameterList node, DartType functionType) { |
bool inferred = false; |
if (_strongMode && node != null && functionType is FunctionType) { |
+ var ts = _typeSystem as StrongTypeSystemImpl; |
void inferType(ParameterElementImpl p, DartType inferredType) { |
// Check that there is no declared type, and that we have not already |
// inferred a type in some fashion. |
if (p.hasImplicitType && |
- (p.type == null || p.type.isDynamic) && |
- !inferredType.isDynamic) { |
- p.type = inferredType; |
- inferred = true; |
+ (p.type == null || p.type.isDynamic)) { |
+ inferredType = ts.upperBoundForType(inferredType); |
+ if (!inferredType.isDynamic) { |
+ p.type = inferredType; |
+ inferred = true; |
+ } |
} |
} |
@@ -628,24 +632,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 +650,39 @@ 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, 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 +727,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 +745,42 @@ 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, 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 +1110,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
staticType = staticElement.type; |
} |
staticType = _inferGenericInstantiationFromContext(node, staticType); |
- |
if (!(_strongMode && |
_inferObjectAccess(node, staticType, prefixedIdentifier))) { |
_recordStaticType(prefixedIdentifier, staticType); |
@@ -1204,7 +1240,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 +1341,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. |
@@ -1620,7 +1654,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.enclosingElement = cls; |
function.isSynthetic = true; |
function.returnType = type.returnType; |
@@ -1903,11 +1941,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 |
@@ -1959,12 +1998,12 @@ 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); |
} |
} |
@@ -1983,7 +2022,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
// ... and finish the inference using that. |
if (argTypes.isNotEmpty && _resolver.isFutureThen(fnType.element)) { |
var firstArgType = argTypes[0]; |
- var firstParamType = paramTypes[0]; |
+ var firstParamType = params[0].type; |
if (firstArgType is FunctionType && |
firstParamType is FunctionType && |
!firstParamType.returnType.isDartAsyncFutureOr) { |
@@ -1998,17 +2037,18 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
// Adjust the expected parameter type to have this return type. |
var function = new FunctionElementImpl(firstParamType.name, -1) |
..isSynthetic = true |
- ..shareParameters(firstParamType.parameters) |
+ ..shareParameters(firstParamType.parameters.toList()) |
..returnType = paramReturnType; |
function.type = new FunctionTypeImpl(function); |
// Use this as the expected 1st parameter type. |
- paramTypes[0] = function.type; |
+ params[0] = new ParameterElementImpl.synthetic( |
+ params[0].name, function.type, params[0].parameterKind); |
} |
} |
} |
- return ts.inferGenericFunctionCall(fnType, paramTypes, argTypes, |
- fnType.returnType, InferenceContext.getContext(node), |
+ return ts.inferGenericFunctionOrType( |
+ fnType, params, argTypes, InferenceContext.getContext(node), |
errorReporter: _resolver.errorReporter, errorNode: errorNode); |
} |
return null; |
@@ -2043,8 +2083,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, |