| 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;
|
| - }
|
| -}
|
|
|