Index: pkg/analyzer/lib/src/summary/link.dart |
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart |
index 3d5a098b6b162df5da02c6ef1073340a847661a6..3cc40fec1c797ee04db10352ba54753d7a849033 100644 |
--- a/pkg/analyzer/lib/src/summary/link.dart |
+++ b/pkg/analyzer/lib/src/summary/link.dart |
@@ -67,6 +67,7 @@ import 'package:analyzer/src/dart/element/type.dart'; |
import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; |
import 'package:analyzer/src/generated/engine.dart'; |
import 'package:analyzer/src/generated/resolver.dart'; |
+import 'package:analyzer/src/generated/static_type_analyzer.dart'; |
import 'package:analyzer/src/generated/utilities_dart.dart'; |
import 'package:analyzer/src/summary/format.dart'; |
import 'package:analyzer/src/summary/idl.dart'; |
@@ -1680,6 +1681,9 @@ class ConstructorElementForLink extends ExecutableElementForLink_NonLocal |
ClassElementImpl get enclosingElement => super.enclosingClass; |
@override |
+ String get identifier => name; |
+ |
+ @override |
bool get isCycleFree { |
if (!_constNode.isEvaluated) { |
new ConstDependencyWalker().walk(_constNode); |
@@ -1687,6 +1691,12 @@ class ConstructorElementForLink extends ExecutableElementForLink_NonLocal |
return _constNode.isCycleFree; |
} |
+ @override |
+ DartType get returnType => enclosingElement.type; |
+ |
+ @override |
+ List<TypeParameterElement> get typeParameters => const []; |
+ |
/** |
* Perform const cycle detection on this constructor. |
*/ |
@@ -2321,27 +2331,47 @@ class ExprTypeComputer { |
} |
void _doInvokeConstructor() { |
- int numNamed = _getNextInt(); |
- int numPositional = _getNextInt(); |
- // TODO(paulberry): don't just pop the args; use their types |
- // to infer the type of type arguments. |
- stack.length -= numNamed + numPositional; |
- strPtr += numNamed; |
+ int numNamed = unlinkedConst.ints[intPtr++]; |
+ int numPositional = unlinkedConst.ints[intPtr++]; |
+ List<String> namedArgNames = _getNextStrings(numNamed); |
+ List<DartType> namedArgTypeList = _popList(numNamed); |
+ List<DartType> positionalArgTypes = _popList(numPositional); |
+ |
EntityRef ref = _getNextRef(); |
- ClassElementForLink_Class element = |
- unit.resolveConstructorClassRef(ref.reference).asClass; |
- if (element != null) { |
- stack.add(element.buildType((int i) { |
- // Type argument explicitly specified. |
- if (i < ref.typeArguments.length) { |
- return unit.resolveTypeRef( |
- ref.typeArguments[i], function.typeParameterContext); |
+ ReferenceableElementForLink refElement = unit.resolveRef(ref.reference); |
+ ConstructorElementForLink constructorElement = refElement.asConstructor; |
+ |
+ if (constructorElement != null) { |
+ stack.add(() { |
+ if (ref.typeArguments.isNotEmpty) { |
+ return constructorElement.enclosingClass.buildType((int i) { |
+ if (i < ref.typeArguments.length) { |
+ return unit.resolveTypeRef( |
+ ref.typeArguments[i], function.typeParameterContext); |
+ } else { |
+ return null; |
+ } |
+ }, const <int>[]); |
} else { |
- return null; |
+ FunctionType rawType = StaticTypeAnalyzer |
+ .constructorToGenericFunctionType(constructorElement); |
+ FunctionType inferredType = _inferExecutableType( |
+ rawType, |
+ numNamed, |
+ numPositional, |
+ namedArgNames, |
+ namedArgTypeList, |
+ positionalArgTypes, const <DartType>[]); |
+ if (identical(inferredType, rawType)) { |
+ inferredType = linker.typeSystem.instantiateToBounds(rawType); |
+ } |
+ return inferredType.returnType; |
} |
- }, const [])); |
+ }()); |
} else { |
- stack.add(DynamicTypeImpl.instance); |
+ ClassElementForLink classElement = |
+ unit.resolveConstructorClassRef(ref.reference).asClass; |
+ stack.add(classElement?.type ?? DynamicTypeImpl.instance); |
} |
} |