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 ab6218ebabf9c56b39e088fef26a524bb925a613..0c8a6c6d979d8510cab718a3ccf54b766ac63ac4 100644 |
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
@@ -164,6 +164,75 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
return inferred; |
} |
+ 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; |
+ } |
+ |
+ 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.5: <blockquote>The static type of a string literal is |
* `String`.</blockquote> |
@@ -649,39 +718,6 @@ 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>, …, |
@@ -744,42 +780,6 @@ 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>, |
@@ -1607,65 +1607,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
return returnType.type; |
} |
- /** |
- * Given a constructor for a generic type, returns the equivalent generic |
- * function type that we could use to forward to the constructor, or for a |
- * non-generic type simply returns the constructor type. |
- * |
- * For example given the type `class C<T> { C(T arg); }`, the generic function |
- * type is `<T>(T) -> C<T>`. |
- */ |
- static 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 |
- // function types. |
- ClassElement cls = constructor.enclosingElement; |
- FunctionType type = constructor.type; |
- if (cls.typeParameters.isEmpty) { |
- return type; |
- } |
- |
- // TODO(jmesserly): feels like we should be able to do this with less code. |
- |
- // Create fresh type formals. This avoids capture if we're inferring the |
- // constructor to the class from inside it. |
- |
- // We build up a substitution for the type parameters, |
- // {variablesFresh/variables} then apply it. |
- var typeVars = <DartType>[]; |
- var freshTypeVars = <DartType>[]; |
- var freshVarElements = <TypeParameterElement>[]; |
- for (int i = 0; i < cls.typeParameters.length; i++) { |
- var typeParamElement = cls.typeParameters[i]; |
- var freshElement = |
- new TypeParameterElementImpl.synthetic(typeParamElement.name); |
- var freshTypeVar = new TypeParameterTypeImpl(freshElement); |
- freshElement.type = freshTypeVar; |
- |
- typeVars.add(typeParamElement.type); |
- freshTypeVars.add(freshTypeVar); |
- freshVarElements.add(freshElement); |
- |
- var bound = typeParamElement.bound ?? DynamicTypeImpl.instance; |
- freshElement.bound = bound.substitute2(freshTypeVars, typeVars); |
- } |
- |
- type = type.substitute2(freshTypeVars, typeVars); |
- |
- 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; |
- function.typeParameters = freshVarElements; |
- function.shareParameters(type.parameters); |
- return function.type = new FunctionTypeImpl(function); |
- } |
- |
DartType _findIteratedType(DartType type, DartType targetType) { |
// TODO(vsm): Use leafp's matchType here? |
// Set by _find if match is found |
@@ -1993,7 +1934,11 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
fnType is FunctionType && |
fnType.typeFormals.isNotEmpty && |
ts is StrongTypeSystemImpl) { |
- // Get the parameters that correspond to the uninstantiated generic. |
+ if (_resolver.isTopLevelInference) { |
+ if (fnType.typeParameters.isNotEmpty) { |
+ return null; |
+ } |
+ } // Get the parameters that correspond to the uninstantiated generic. |
List<ParameterElement> rawParameters = ResolverVisitor |
.resolveArgumentsToParameters(argumentList, fnType.parameters, null); |
@@ -2352,6 +2297,65 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
} |
/** |
+ * Given a constructor for a generic type, returns the equivalent generic |
+ * function type that we could use to forward to the constructor, or for a |
+ * non-generic type simply returns the constructor type. |
+ * |
+ * For example given the type `class C<T> { C(T arg); }`, the generic function |
+ * type is `<T>(T) -> C<T>`. |
+ */ |
+ static 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 |
+ // function types. |
+ ClassElement cls = constructor.enclosingElement; |
+ FunctionType type = constructor.type; |
+ if (cls.typeParameters.isEmpty) { |
+ return type; |
+ } |
+ |
+ // TODO(jmesserly): feels like we should be able to do this with less code. |
+ |
+ // Create fresh type formals. This avoids capture if we're inferring the |
+ // constructor to the class from inside it. |
+ |
+ // We build up a substitution for the type parameters, |
+ // {variablesFresh/variables} then apply it. |
+ var typeVars = <DartType>[]; |
+ var freshTypeVars = <DartType>[]; |
+ var freshVarElements = <TypeParameterElement>[]; |
+ for (int i = 0; i < cls.typeParameters.length; i++) { |
+ var typeParamElement = cls.typeParameters[i]; |
+ var freshElement = |
+ new TypeParameterElementImpl.synthetic(typeParamElement.name); |
+ var freshTypeVar = new TypeParameterTypeImpl(freshElement); |
+ freshElement.type = freshTypeVar; |
+ |
+ typeVars.add(typeParamElement.type); |
+ freshTypeVars.add(freshTypeVar); |
+ freshVarElements.add(freshElement); |
+ |
+ var bound = typeParamElement.bound ?? DynamicTypeImpl.instance; |
+ freshElement.bound = bound.substitute2(freshTypeVars, typeVars); |
+ } |
+ |
+ type = type.substitute2(freshTypeVars, typeVars); |
+ |
+ 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; |
+ function.typeParameters = freshVarElements; |
+ function.shareParameters(type.parameters); |
+ return function.type = new FunctionTypeImpl(function); |
+ } |
+ |
+ /** |
* Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that |
* implement those tags. |
* |