Index: pkg/compiler/lib/src/inferrer/inferrer_engine.dart |
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart |
index 232f83685e9234289828b3671d7a056667becc30..5ed4215b159efb16ca85e4018747508e825b9d1e 100644 |
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart |
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart |
@@ -7,32 +7,29 @@ import 'package:kernel/ast.dart' as ir; |
import '../common.dart'; |
import '../common/names.dart'; |
import '../compiler.dart'; |
-import '../constants/expressions.dart'; |
-import '../constants/values.dart'; |
import '../common_elements.dart'; |
-import '../elements/elements.dart'; |
+import '../elements/elements.dart' |
+ show |
+ ClassElement, |
+ ConstructorElement, |
+ Elements, |
+ MemberElement, |
+ ParameterElement; |
import '../elements/entities.dart'; |
import '../elements/names.dart'; |
import '../js_backend/annotations.dart'; |
import '../js_backend/js_backend.dart'; |
import '../native/behavior.dart' as native; |
-import '../resolution/tree_elements.dart'; |
-import '../tree/nodes.dart' as ast; |
-import '../types/constants.dart'; |
import '../types/types.dart'; |
import '../universe/call_structure.dart'; |
import '../universe/selector.dart'; |
import '../universe/side_effects.dart'; |
-import '../util/util.dart'; |
import '../world.dart'; |
-import 'closure_tracer.dart'; |
import 'debug.dart' as debug; |
import 'locals_handler.dart'; |
import 'list_tracer.dart'; |
import 'map_tracer.dart'; |
import 'builder.dart'; |
-import 'builder_kernel.dart'; |
-import 'type_graph_dump.dart'; |
import 'type_graph_inferrer.dart'; |
import 'type_graph_nodes.dart'; |
import 'type_system.dart'; |
@@ -40,7 +37,7 @@ import 'type_system.dart'; |
/// An inferencing engine that computes a call graph of [TypeInformation] nodes |
/// by visiting the AST of the application, and then does the inferencing on the |
/// graph. |
-abstract class InferrerEngine { |
+abstract class InferrerEngine<T> { |
/// A set of selector names that [List] implements, that we know return their |
/// element type. |
final Set<Selector> returnsListElementTypeSet = |
@@ -64,8 +61,8 @@ abstract class InferrerEngine { |
CommonMasks get commonMasks => closedWorld.commonMasks; |
CommonElements get commonElements => closedWorld.commonElements; |
- TypeSystem<ast.Node> get types; |
- Map<ast.Node, TypeInformation> get concreteTypes; |
+ TypeSystem<T> get types; |
+ Map<T, TypeInformation> get concreteTypes; |
/// Parallel structure for concreteTypes. |
// TODO(efortuna): Remove concreteTypes and/or parameterize InferrerEngine by |
@@ -76,7 +73,7 @@ abstract class InferrerEngine { |
void runOverAllElements(); |
- void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments); |
+ void analyze(MemberEntity member, T node, ArgumentsTypes arguments); |
void analyzeListAndEnqueue(ListTypeInformation info); |
void analyzeMapAndEnqueue(MapTypeInformation info); |
@@ -136,11 +133,11 @@ abstract class InferrerEngine { |
/// Registers a call to await with an expression of type [argumentType] as |
/// argument. |
- TypeInformation registerAwait(ast.Node node, TypeInformation argument); |
+ TypeInformation registerAwait(T node, TypeInformation argument); |
/// Registers a call to yield with an expression of type [argumentType] as |
/// argument. |
- TypeInformation registerYield(ast.Node node, TypeInformation argument); |
+ TypeInformation registerYield(T node, TypeInformation argument); |
/// Registers that [caller] calls [closure] with [arguments]. |
/// |
@@ -149,7 +146,7 @@ abstract class InferrerEngine { |
/// |
/// [inLoop] tells whether the call happens in a loop. |
TypeInformation registerCalledClosure( |
- ast.Node node, |
+ T node, |
Selector selector, |
TypeMask mask, |
TypeInformation closure, |
@@ -184,7 +181,7 @@ abstract class InferrerEngine { |
/// [inLoop] tells whether the call happens in a loop. |
TypeInformation registerCalledSelector( |
CallType callType, |
- ast.Node node, |
+ T node, |
Selector selector, |
TypeMask mask, |
TypeInformation receiverType, |
@@ -201,8 +198,8 @@ abstract class InferrerEngine { |
ArgumentsTypes arguments, Selector selector, TypeMask mask, |
{bool remove, bool addToQueue: true}); |
- void updateSelectorInMember(MemberEntity owner, CallType callType, |
- ast.Node node, Selector selector, TypeMask mask); |
+ void updateSelectorInMember(MemberEntity owner, CallType callType, T node, |
+ Selector selector, TypeMask mask); |
/// Returns the return type of [element]. |
TypeInformation returnTypeOfMember(MemberEntity element); |
@@ -228,7 +225,7 @@ abstract class InferrerEngine { |
void clear(); |
} |
-class InferrerEngineImpl extends InferrerEngine { |
+abstract class InferrerEngineImpl<T> extends InferrerEngine<T> { |
final Map<Local, TypeInformation> defaultTypeOfParameter = |
new Map<Local, TypeInformation>(); |
final WorkQueue workQueue = new WorkQueue(); |
@@ -249,9 +246,8 @@ class InferrerEngineImpl extends InferrerEngine { |
final ClosedWorld closedWorld; |
final ClosedWorldRefiner closedWorldRefiner; |
- final TypeSystem<ast.Node> types; |
- final Map<ast.Node, TypeInformation> concreteTypes = |
- new Map<ast.Node, TypeInformation>(); |
+ final TypeSystem<T> types; |
+ final Map<T, TypeInformation> concreteTypes = new Map<T, TypeInformation>(); |
final Map<ir.Node, TypeInformation> concreteKernelTypes = |
new Map<ir.Node, TypeInformation>(); |
@@ -263,10 +259,13 @@ class InferrerEngineImpl extends InferrerEngine { |
final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData = |
new Map<MemberEntity, GlobalTypeInferenceElementData>(); |
- InferrerEngineImpl(this.compiler, ClosedWorld closedWorld, |
- this.closedWorldRefiner, this.mainElement) |
- : this.types = new TypeSystem<ast.Node>( |
- closedWorld, const TypeSystemStrategyImpl()), |
+ InferrerEngineImpl( |
+ this.compiler, |
+ ClosedWorld closedWorld, |
+ this.closedWorldRefiner, |
+ this.mainElement, |
+ TypeSystemStrategy<T> typeSystemStrategy) |
+ : this.types = new TypeSystem<T>(closedWorld, typeSystemStrategy), |
this.closedWorld = closedWorld; |
void forEachElementMatching( |
@@ -277,12 +276,13 @@ class InferrerEngineImpl extends InferrerEngine { |
} |
} |
+ GlobalTypeInferenceElementData<T> createElementData(); |
+ |
// TODO(johnniwinther): Make this private again. |
- GlobalTypeInferenceElementData dataOfMember(MemberEntity element) => |
- _memberData.putIfAbsent( |
- element, () => new GlobalTypeInferenceElementData()); |
+ GlobalTypeInferenceElementData<T> dataOfMember(MemberEntity element) => |
+ _memberData.putIfAbsent(element, createElementData); |
- GlobalTypeInferenceElementData lookupDataOfMember(MemberEntity element) => |
+ GlobalTypeInferenceElementData<T> lookupDataOfMember(MemberEntity element) => |
_memberData[element]; |
/** |
@@ -358,8 +358,8 @@ class InferrerEngineImpl extends InferrerEngine { |
return returnType; |
} |
- void updateSelectorInMember(MemberEntity owner, CallType callType, |
- ast.Node node, Selector selector, TypeMask mask) { |
+ void updateSelectorInMember(MemberEntity owner, CallType callType, T node, |
+ Selector selector, TypeMask mask) { |
GlobalTypeInferenceElementData data = dataOfMember(owner); |
assert(validCallType(callType, node)); |
switch (callType) { |
@@ -456,280 +456,9 @@ class InferrerEngineImpl extends InferrerEngine { |
workQueue.add(info); |
} |
- void runOverAllElements() { |
- if (compiler.disableTypeInference) return; |
- if (compiler.options.verbose) { |
- compiler.progress.reset(); |
- } |
- sortResolvedAsts().forEach((ResolvedAst resolvedAst) { |
- if (compiler.shouldPrintProgress) { |
- reporter.log('Added $addedInGraph elements in inferencing graph.'); |
- compiler.progress.reset(); |
- } |
- // This also forces the creation of the [ElementTypeInformation] to ensure |
- // it is in the graph. |
- MemberElement member = resolvedAst.element; |
- types.withMember(member, () => analyze(resolvedAst, null)); |
- }); |
- reporter.log('Added $addedInGraph elements in inferencing graph.'); |
- |
- TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null; |
- |
- dump?.beforeAnalysis(); |
- buildWorkQueue(); |
- refine(); |
- |
- // Try to infer element types of lists and compute their escape information. |
- types.allocatedLists.values.forEach((TypeInformation info) { |
- analyzeListAndEnqueue(info); |
- }); |
- |
- // Try to infer the key and value types for maps and compute the values' |
- // escape information. |
- types.allocatedMaps.values.forEach((TypeInformation info) { |
- analyzeMapAndEnqueue(info); |
- }); |
- |
- Set<FunctionEntity> bailedOutOn = new Set<FunctionEntity>(); |
- |
- // Trace closures to potentially infer argument types. |
- types.allocatedClosures.forEach((dynamic info) { |
- void trace( |
- Iterable<FunctionEntity> elements, ClosureTracerVisitor tracer) { |
- tracer.run(); |
- if (!tracer.continueAnalyzing) { |
- elements.forEach((FunctionEntity _element) { |
- MethodElement element = _element; |
- MethodElement implementation = element.implementation; |
- closedWorldRefiner.registerMightBePassedToApply(element); |
- if (debug.VERBOSE) { |
- print("traced closure $element as ${true} (bail)"); |
- } |
- implementation.functionSignature |
- .forEachParameter((FormalElement _parameter) { |
- ParameterElement parameter = _parameter; |
- types |
- .getInferredTypeOfParameter(parameter) |
- .giveUp(this, clearAssignments: false); |
- }); |
- }); |
- bailedOutOn.addAll(elements); |
- return; |
- } |
- elements |
- .where((e) => !bailedOutOn.contains(e)) |
- .forEach((FunctionEntity _element) { |
- MethodElement element = _element; |
- MethodElement implementation = element.implementation; |
- implementation.functionSignature |
- .forEachParameter((FormalElement _parameter) { |
- ParameterElement parameter = _parameter; |
- ParameterTypeInformation info = |
- types.getInferredTypeOfParameter(parameter); |
- info.maybeResume(); |
- workQueue.add(info); |
- }); |
- if (tracer.tracedType.mightBePassedToFunctionApply) { |
- closedWorldRefiner.registerMightBePassedToApply(element); |
- } |
- if (debug.VERBOSE) { |
- print("traced closure $element as " |
- "${closedWorldRefiner |
- .getCurrentlyKnownMightBePassedToApply(element)}"); |
- } |
- }); |
- } |
- |
- if (info is ClosureTypeInformation) { |
- Iterable<FunctionEntity> elements = [info.closure]; |
- trace(elements, new ClosureTracerVisitor(elements, info, this)); |
- } else if (info is CallSiteTypeInformation) { |
- if (info is StaticCallSiteTypeInformation && |
- info.selector != null && |
- info.selector.isCall) { |
- // This is a constructor call to a class with a call method. So we |
- // need to trace the call method here. |
- MethodElement calledElement = info.calledElement; |
- assert(calledElement.isGenerativeConstructor); |
- ClassElement cls = calledElement.enclosingClass; |
- MethodElement callMethod = cls.lookupMember(Identifiers.call); |
- if (callMethod == null) { |
- callMethod = cls.lookupMember(Identifiers.noSuchMethod_); |
- } |
- assert(callMethod != null, failedAt(cls)); |
- Iterable<FunctionEntity> elements = [callMethod]; |
- trace(elements, new ClosureTracerVisitor(elements, info, this)); |
- } else { |
- // We only are interested in functions here, as other targets |
- // of this closure call are not a root to trace but an intermediate |
- // for some other function. |
- Iterable<FunctionEntity> elements = new List<FunctionEntity>.from( |
- info.callees.where((e) => e.isFunction)); |
- trace(elements, new ClosureTracerVisitor(elements, info, this)); |
- } |
- } else if (info is MemberTypeInformation) { |
- trace(<FunctionEntity>[info.member], |
- new StaticTearOffClosureTracerVisitor(info.member, info, this)); |
- } else if (info is ParameterTypeInformation) { |
- failedAt( |
- NO_LOCATION_SPANNABLE, 'Unexpected closure allocation info $info'); |
- } |
- }); |
- |
- dump?.beforeTracing(); |
- |
- // Reset all nodes that use lists/maps that have been inferred, as well |
- // as nodes that use elements fetched from these lists/maps. The |
- // workset for a new run of the analysis will be these nodes. |
- Set<TypeInformation> seenTypes = new Set<TypeInformation>(); |
- while (!workQueue.isEmpty) { |
- TypeInformation info = workQueue.remove(); |
- if (seenTypes.contains(info)) continue; |
- // If the node cannot be reset, we do not need to update its users either. |
- if (!info.reset(this)) continue; |
- seenTypes.add(info); |
- workQueue.addAll(info.users); |
- } |
- |
- workQueue.addAll(seenTypes); |
- refine(); |
- |
- if (debug.PRINT_SUMMARY) { |
- types.allocatedLists.values.forEach((_info) { |
- ListTypeInformation info = _info; |
- print('${info.type} ' |
- 'for ${info.originalType.allocationNode} ' |
- 'at ${info.originalType.allocationElement} ' |
- 'after ${info.refineCount}'); |
- }); |
- types.allocatedMaps.values.forEach((_info) { |
- MapTypeInformation info = _info; |
- print('${info.type} ' |
- 'for ${info.originalType.allocationNode} ' |
- 'at ${info.originalType.allocationElement} ' |
- 'after ${info.refineCount}'); |
- }); |
- types.allocatedClosures.forEach((TypeInformation info) { |
- if (info is ElementTypeInformation) { |
- print('${info.getInferredSignature(types)} for ' |
- '${info.debugName}'); |
- } else if (info is ClosureTypeInformation) { |
- print('${info.getInferredSignature(types)} for ' |
- '${info.debugName}'); |
- } else if (info is DynamicCallSiteTypeInformation) { |
- for (MemberEntity target in info.targets) { |
- if (target is FunctionEntity) { |
- print( |
- '${types.getInferredSignatureOfMethod(target)} for ${target}'); |
- } else { |
- print( |
- '${types.getInferredTypeOfMember(target).type} for ${target}'); |
- } |
- } |
- } else if (info is StaticCallSiteTypeInformation) { |
- ClassElement cls = info.calledElement.enclosingClass; |
- MethodElement callMethod = cls.lookupMember(Identifiers.call); |
- print('${types.getInferredSignatureOfMethod(callMethod)} for ${cls}'); |
- } else { |
- print('${info.type} for some unknown kind of closure'); |
- } |
- }); |
- analyzedElements.forEach((MemberEntity elem) { |
- TypeInformation type = types.getInferredTypeOfMember(elem); |
- print('${elem} :: ${type} from ${type.assignments} '); |
- }); |
- } |
- dump?.afterAnalysis(); |
- |
- reporter.log('Inferred $overallRefineCount types.'); |
+ void runOverAllElements(); |
- processLoopInformation(); |
- } |
- |
- void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments) { |
- MemberElement element = resolvedAst.element; |
- if (analyzedElements.contains(element)) return; |
- analyzedElements.add(element); |
- |
- dynamic visitor = compiler.options.kernelGlobalInference |
- ? new KernelTypeGraphBuilder(element, resolvedAst, compiler, this) |
- : new ElementGraphBuilder(element, resolvedAst, compiler, this); |
- TypeInformation type; |
- reporter.withCurrentElement(element, () { |
- // ignore: UNDEFINED_METHOD |
- type = visitor.run(); |
- }); |
- addedInGraph++; |
- |
- if (element.isField) { |
- FieldElement field = element; |
- ast.Node initializer = resolvedAst.body; |
- if (field.isFinal || field.isConst) { |
- // If [element] is final and has an initializer, we record |
- // the inferred type. |
- if (resolvedAst.body != null) { |
- if (type is! ListTypeInformation && type is! MapTypeInformation) { |
- // For non-container types, the constant handler does |
- // constant folding that could give more precise results. |
- ConstantExpression constant = field.constant; |
- if (constant != null) { |
- ConstantValue value = |
- compiler.backend.constants.getConstantValue(constant); |
- if (value != null) { |
- if (value.isFunction) { |
- FunctionConstantValue functionConstant = value; |
- MethodElement function = functionConstant.element; |
- type = types.allocateClosure(function); |
- } else { |
- // Although we might find a better type, we have to keep |
- // the old type around to ensure that we get a complete view |
- // of the type graph and do not drop any flow edges. |
- TypeMask refinedType = computeTypeMask(closedWorld, value); |
- assert(TypeMask.assertIsNormalized(refinedType, closedWorld)); |
- type = new NarrowTypeInformation(type, refinedType); |
- types.allocatedTypes.add(type); |
- } |
- } else { |
- assert( |
- field.isInstanceMember || |
- constant.isImplicit || |
- constant.isPotential, |
- failedAt( |
- field, |
- "Constant expression without value: " |
- "${constant.toStructuredText()}.")); |
- } |
- } |
- } |
- recordTypeOfField(field, type); |
- } else if (!element.isInstanceMember) { |
- recordTypeOfField(field, types.nullType); |
- } |
- } else if (initializer == null) { |
- // Only update types of static fields if there is no |
- // assignment. Instance fields are dealt with in the constructor. |
- if (Elements.isStaticOrTopLevelField(element)) { |
- recordTypeOfField(field, type); |
- } |
- } else { |
- recordTypeOfField(field, type); |
- } |
- if (Elements.isStaticOrTopLevelField(field) && |
- resolvedAst.body != null && |
- !element.isConst) { |
- dynamic argument = resolvedAst.body; |
- // TODO(13429): We could do better here by using the |
- // constant handler to figure out if it's a lazy field or not. |
- if (argument.asSend() != null || |
- (argument.asNewExpression() != null && !argument.isConst)) { |
- recordTypeOfField(field, types.nullType); |
- } |
- } |
- } else { |
- MethodElement method = element; |
- recordReturnType(method, type); |
- } |
- } |
+ void analyze(MemberEntity element, T body, ArgumentsTypes arguments); |
void processLoopInformation() { |
types.allocatedCalls.forEach((dynamic info) { |
@@ -789,77 +518,7 @@ class InferrerEngineImpl extends InferrerEngine { |
void updateParameterAssignments(TypeInformation caller, MemberEntity callee, |
ArgumentsTypes arguments, Selector selector, TypeMask mask, |
- {bool remove, bool addToQueue: true}) { |
- if (callee.name == Identifiers.noSuchMethod_) return; |
- if (callee.isField) { |
- if (selector.isSetter) { |
- ElementTypeInformation info = types.getInferredTypeOfMember(callee); |
- if (remove) { |
- info.removeAssignment(arguments.positional[0]); |
- } else { |
- info.addAssignment(arguments.positional[0]); |
- } |
- if (addToQueue) workQueue.add(info); |
- } |
- } else if (callee.isGetter) { |
- return; |
- } else if (selector != null && selector.isGetter) { |
- // We are tearing a function off and thus create a closure. |
- assert(callee.isFunction); |
- MethodElement method = callee; |
- MemberTypeInformation info = types.getInferredTypeOfMember(method); |
- if (remove) { |
- info.closurizedCount--; |
- } else { |
- info.closurizedCount++; |
- if (Elements.isStaticOrTopLevel(method)) { |
- types.allocatedClosures.add(info); |
- } else { |
- // We add the call-site type information here so that we |
- // can benefit from further refinement of the selector. |
- types.allocatedClosures.add(caller); |
- } |
- FunctionElement function = method.implementation; |
- FunctionSignature signature = function.functionSignature; |
- signature.forEachParameter((FormalElement _parameter) { |
- ParameterElement parameter = _parameter; |
- ParameterTypeInformation info = |
- types.getInferredTypeOfParameter(parameter); |
- info.tagAsTearOffClosureParameter(this); |
- if (addToQueue) workQueue.add(info); |
- }); |
- } |
- } else { |
- MethodElement method = callee; |
- FunctionElement function = method.implementation; |
- FunctionSignature signature = function.functionSignature; |
- int parameterIndex = 0; |
- bool visitingRequiredParameter = true; |
- signature.forEachParameter((FormalElement _parameter) { |
- ParameterElement parameter = _parameter; |
- if (signature.hasOptionalParameters && |
- parameter == signature.optionalParameters.first) { |
- visitingRequiredParameter = false; |
- } |
- TypeInformation type = visitingRequiredParameter |
- ? arguments.positional[parameterIndex] |
- : signature.optionalParametersAreNamed |
- ? arguments.named[parameter.name] |
- : parameterIndex < arguments.positional.length |
- ? arguments.positional[parameterIndex] |
- : null; |
- if (type == null) type = getDefaultTypeOfParameter(parameter); |
- TypeInformation info = types.getInferredTypeOfParameter(parameter); |
- if (remove) { |
- info.removeAssignment(type); |
- } else { |
- info.addAssignment(type); |
- } |
- parameterIndex++; |
- if (addToQueue) workQueue.add(info); |
- }); |
- } |
- } |
+ {bool remove, bool addToQueue: true}); |
void setDefaultTypeOfParameter(Local parameter, TypeInformation type, |
{bool isInstanceMember}) { |
@@ -982,7 +641,7 @@ class InferrerEngineImpl extends InferrerEngine { |
TypeInformation registerCalledSelector( |
CallType callType, |
- ast.Node node, |
+ T node, |
Selector selector, |
TypeMask mask, |
TypeInformation receiverType, |
@@ -1017,24 +676,24 @@ class InferrerEngineImpl extends InferrerEngine { |
return info; |
} |
- TypeInformation registerAwait(ast.Node node, TypeInformation argument) { |
+ TypeInformation registerAwait(T node, TypeInformation argument) { |
AwaitTypeInformation info = |
- new AwaitTypeInformation<ast.Node>(types.currentMember, node); |
+ new AwaitTypeInformation<T>(types.currentMember, node); |
info.addAssignment(argument); |
types.allocatedTypes.add(info); |
return info; |
} |
- TypeInformation registerYield(ast.Node node, TypeInformation argument) { |
+ TypeInformation registerYield(T node, TypeInformation argument) { |
YieldTypeInformation info = |
- new YieldTypeInformation<ast.Node>(types.currentMember, node); |
+ new YieldTypeInformation<T>(types.currentMember, node); |
info.addAssignment(argument); |
types.allocatedTypes.add(info); |
return info; |
} |
TypeInformation registerCalledClosure( |
- ast.Node node, |
+ T node, |
Selector selector, |
TypeMask mask, |
TypeInformation closure, |
@@ -1058,46 +717,6 @@ class InferrerEngineImpl extends InferrerEngine { |
return info; |
} |
- // Sorts the resolved elements by size. We do this for this inferrer |
- // to get the same results for [ListTracer] compared to the |
- // [SimpleTypesInferrer]. |
- Iterable<ResolvedAst> sortResolvedAsts() { |
- int max = 0; |
- Map<int, Setlet<ResolvedAst>> methodSizes = <int, Setlet<ResolvedAst>>{}; |
- compiler.enqueuer.resolution.processedEntities.forEach((_element) { |
- MemberElement element = _element; |
- ResolvedAst resolvedAst = element.resolvedAst; |
- element = element.implementation; |
- if (element.impliesType) return; |
- assert( |
- element.isField || |
- element.isFunction || |
- element.isConstructor || |
- element.isGetter || |
- element.isSetter, |
- failedAt(element, 'Unexpected element kind: ${element.kind}')); |
- if (element.isAbstract) return; |
- // Put the other operators in buckets by length, later to be added in |
- // length order. |
- int length = 0; |
- if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
- TreeElementMapping mapping = resolvedAst.elements; |
- length = mapping.getSelectorCount(); |
- } |
- max = length > max ? length : max; |
- Setlet<ResolvedAst> set = |
- methodSizes.putIfAbsent(length, () => new Setlet<ResolvedAst>()); |
- set.add(resolvedAst); |
- }); |
- |
- List<ResolvedAst> result = <ResolvedAst>[]; |
- for (int i = 0; i <= max; i++) { |
- Setlet<ResolvedAst> set = methodSizes[i]; |
- if (set != null) result.addAll(set); |
- } |
- return result; |
- } |
- |
void clear() { |
void cleanup(TypeInformation info) => info.cleanup(); |
@@ -1162,104 +781,3 @@ class InferrerEngineImpl extends InferrerEngine { |
} |
} |
} |
- |
-class TypeSystemStrategyImpl implements TypeSystemStrategy<ast.Node> { |
- const TypeSystemStrategyImpl(); |
- |
- @override |
- MemberTypeInformation createMemberTypeInformation( |
- covariant MemberElement member) { |
- assert(member.isDeclaration, failedAt(member)); |
- if (member.isField) { |
- FieldElement field = member; |
- return new FieldTypeInformation(field, field.type); |
- } else if (member.isGetter) { |
- GetterElement getter = member; |
- return new GetterTypeInformation(getter, getter.type); |
- } else if (member.isSetter) { |
- SetterElement setter = member; |
- return new SetterTypeInformation(setter); |
- } else if (member.isFunction) { |
- MethodElement method = member; |
- return new MethodTypeInformation(method, method.type); |
- } else { |
- ConstructorElement constructor = member; |
- if (constructor.isFactoryConstructor) { |
- return new FactoryConstructorTypeInformation( |
- constructor, constructor.type); |
- } else { |
- return new GenerativeConstructorTypeInformation(constructor); |
- } |
- } |
- } |
- |
- @override |
- ParameterTypeInformation createParameterTypeInformation( |
- covariant ParameterElement parameter, TypeSystem<ast.Node> types) { |
- assert(parameter.isImplementation, failedAt(parameter)); |
- FunctionTypedElement function = parameter.functionDeclaration.declaration; |
- if (function.isLocal) { |
- LocalFunctionElement localFunction = function; |
- MethodElement callMethod = localFunction.callMethod; |
- return new ParameterTypeInformation.localFunction( |
- types.getInferredTypeOfMember(callMethod), |
- parameter, |
- parameter.type, |
- callMethod); |
- } else if (function.isInstanceMember) { |
- MethodElement method = function; |
- return new ParameterTypeInformation.instanceMember( |
- types.getInferredTypeOfMember(method), |
- parameter, |
- parameter.type, |
- method, |
- new ParameterAssignments()); |
- } else { |
- MethodElement method = function; |
- return new ParameterTypeInformation.static( |
- types.getInferredTypeOfMember(method), |
- parameter, |
- parameter.type, |
- method, |
- // TODO(johnniwinther): Is this still valid now that initializing |
- // formals also introduce locals? |
- isInitializingFormal: parameter.isInitializingFormal); |
- } |
- } |
- |
- @override |
- void forEachParameter( |
- covariant MethodElement function, void f(Local parameter)) { |
- MethodElement impl = function.implementation; |
- FunctionSignature signature = impl.functionSignature; |
- signature.forEachParameter((FormalElement _parameter) { |
- ParameterElement parameter = _parameter; |
- f(parameter); |
- }); |
- } |
- |
- @override |
- bool checkMapNode(ast.Node node) { |
- return node is ast.LiteralMap; |
- } |
- |
- @override |
- bool checkListNode(ast.Node node) { |
- return node is ast.LiteralList || node is ast.Send; |
- } |
- |
- @override |
- bool checkLoopPhiNode(ast.Node node) { |
- return node is ast.Loop || node is ast.SwitchStatement; |
- } |
- |
- @override |
- bool checkPhiNode(ast.Node node) { |
- return true; |
- } |
- |
- @override |
- bool checkClassEntity(covariant ClassElement cls) { |
- return cls.isDeclaration; |
- } |
-} |