| Index: pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
|
| diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
|
| index f12a8b43141afa22c33d740d3821037f4814e654..e19436fb5372dfa700d311181312e848fc495ea8 100644
|
| --- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
|
| +++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
|
| @@ -7,52 +7,26 @@ library type_graph_inferrer;
|
| import 'dart:collection' show Queue;
|
|
|
| import '../common.dart';
|
| -import '../common/names.dart' show
|
| - Identifiers,
|
| - Names;
|
| -import '../compiler.dart' show
|
| - Compiler;
|
| +import '../common/names.dart' show Identifiers, Names;
|
| +import '../compiler.dart' show Compiler;
|
| import '../constants/values.dart';
|
| -import '../dart_types.dart' show
|
| - DartType,
|
| - FunctionType,
|
| - InterfaceType,
|
| - TypeKind;
|
| +import '../dart_types.dart'
|
| + show DartType, FunctionType, InterfaceType, TypeKind;
|
| import '../elements/elements.dart';
|
| -import '../js_backend/js_backend.dart' show
|
| - Annotations,
|
| - JavaScriptBackend;
|
| -import '../resolution/tree_elements.dart' show
|
| - TreeElementMapping;
|
| -import '../tree/tree.dart' as ast show
|
| - DartString,
|
| - Node,
|
| - LiteralBool,
|
| - Send,
|
| - SendSet,
|
| - TryStatement;
|
| -import '../types/types.dart' show
|
| - ContainerTypeMask,
|
| - MapTypeMask,
|
| - TypeMask,
|
| - TypesInferrer;
|
| -import '../types/constants.dart' show
|
| - computeTypeMask;
|
| -import '../universe/call_structure.dart' show
|
| - CallStructure;
|
| -import '../universe/selector.dart' show
|
| - Selector;
|
| -import '../universe/side_effects.dart' show
|
| - SideEffects;
|
| -import '../util/util.dart' show
|
| - ImmutableEmptySet,
|
| - Setlet;
|
| -import '../world.dart' show
|
| - ClassWorld;
|
| -
|
| -import 'inferrer_visitor.dart' show
|
| - ArgumentsTypes,
|
| - TypeSystem;
|
| +import '../js_backend/js_backend.dart' show Annotations, JavaScriptBackend;
|
| +import '../resolution/tree_elements.dart' show TreeElementMapping;
|
| +import '../tree/tree.dart' as ast
|
| + show DartString, Node, LiteralBool, Send, SendSet, TryStatement;
|
| +import '../types/types.dart'
|
| + show ContainerTypeMask, MapTypeMask, TypeMask, TypesInferrer;
|
| +import '../types/constants.dart' show computeTypeMask;
|
| +import '../universe/call_structure.dart' show CallStructure;
|
| +import '../universe/selector.dart' show Selector;
|
| +import '../universe/side_effects.dart' show SideEffects;
|
| +import '../util/util.dart' show ImmutableEmptySet, Setlet;
|
| +import '../world.dart' show ClassWorld;
|
| +
|
| +import 'inferrer_visitor.dart' show ArgumentsTypes, TypeSystem;
|
| import 'simple_types_inferrer.dart';
|
|
|
| import 'closure_tracer.dart';
|
| @@ -62,7 +36,6 @@ import 'type_graph_nodes.dart';
|
| import 'type_graph_dump.dart';
|
| import 'debug.dart' as debug;
|
|
|
| -
|
| class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| final Compiler compiler;
|
| final ClassWorld classWorld;
|
| @@ -90,13 +63,14 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| /// narrowing, phis, and containers).
|
| final List<TypeInformation> allocatedTypes = <TypeInformation>[];
|
|
|
| - Iterable<TypeInformation> get allTypes =>
|
| - [typeInformations.values,
|
| - allocatedLists.values,
|
| - allocatedMaps.values,
|
| - allocatedClosures,
|
| - concreteTypes.values,
|
| - allocatedTypes].expand((x) => x);
|
| + Iterable<TypeInformation> get allTypes => [
|
| + typeInformations.values,
|
| + allocatedLists.values,
|
| + allocatedMaps.values,
|
| + allocatedClosures,
|
| + concreteTypes.values,
|
| + allocatedTypes
|
| + ].expand((x) => x);
|
|
|
| TypeInformationSystem(Compiler compiler)
|
| : this.compiler = compiler,
|
| @@ -264,8 +238,8 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return new BoolLiteralTypeInformation(value, compiler.typesTask.boolType);
|
| }
|
|
|
| - TypeInformation computeLUB(TypeInformation firstType,
|
| - TypeInformation secondType) {
|
| + TypeInformation computeLUB(
|
| + TypeInformation firstType, TypeInformation secondType) {
|
| if (firstType == null) return secondType;
|
| if (firstType == secondType) return firstType;
|
| if (firstType == nonNullEmptyType) return secondType;
|
| @@ -281,11 +255,8 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return info.type != mask;
|
| }
|
|
|
| - TypeInformation refineReceiver(
|
| - Selector selector,
|
| - TypeMask mask,
|
| - TypeInformation receiver,
|
| - bool isConditional) {
|
| + TypeInformation refineReceiver(Selector selector, TypeMask mask,
|
| + TypeInformation receiver, bool isConditional) {
|
| if (receiver.type.isExact) return receiver;
|
| TypeMask otherType =
|
| compiler.world.allFunctions.receiverType(selector, mask);
|
| @@ -307,9 +278,8 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return newType;
|
| }
|
|
|
| - TypeInformation narrowType(TypeInformation type,
|
| - DartType annotation,
|
| - {bool isNullable: true}) {
|
| + TypeInformation narrowType(TypeInformation type, DartType annotation,
|
| + {bool isNullable: true}) {
|
| if (annotation.treatAsDynamic) return type;
|
| if (annotation.isVoid) return nullType;
|
| if (annotation.element == classWorld.objectClass && isNullable) return type;
|
| @@ -396,24 +366,21 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return type == nullType;
|
| }
|
|
|
| - TypeInformation allocateList(TypeInformation type,
|
| - ast.Node node,
|
| - Element enclosing,
|
| - [TypeInformation elementType, int length]) {
|
| - bool isTypedArray =
|
| - compiler.typedDataClass != null &&
|
| + TypeInformation allocateList(
|
| + TypeInformation type, ast.Node node, Element enclosing,
|
| + [TypeInformation elementType, int length]) {
|
| + bool isTypedArray = compiler.typedDataClass != null &&
|
| classWorld.isInstantiated(compiler.typedDataClass) &&
|
| type.type.satisfies(compiler.typedDataClass, classWorld);
|
| bool isConst = (type.type == compiler.typesTask.constListType);
|
| bool isFixed = (type.type == compiler.typesTask.fixedListType) ||
|
| - isConst ||
|
| - isTypedArray;
|
| + isConst ||
|
| + isTypedArray;
|
| bool isElementInferred = isConst || isTypedArray;
|
|
|
| int inferredLength = isFixed ? length : null;
|
| - TypeMask elementTypeMask = isElementInferred
|
| - ? elementType.type
|
| - : dynamicType.type;
|
| + TypeMask elementTypeMask =
|
| + isElementInferred ? elementType.type : dynamicType.type;
|
| ContainerTypeMask mask = new ContainerTypeMask(
|
| type.type, node, enclosing, elementTypeMask, inferredLength);
|
| ElementInContainerTypeInformation element =
|
| @@ -432,11 +399,9 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return result;
|
| }
|
|
|
| - TypeInformation allocateMap(ConcreteTypeInformation type,
|
| - ast.Node node,
|
| - Element element,
|
| - [List<TypeInformation> keyTypes,
|
| - List<TypeInformation> valueTypes]) {
|
| + TypeInformation allocateMap(
|
| + ConcreteTypeInformation type, ast.Node node, Element element,
|
| + [List<TypeInformation> keyTypes, List<TypeInformation> valueTypes]) {
|
| assert(keyTypes.length == valueTypes.length);
|
| bool isFixed = (type.type == compiler.typesTask.constMapType);
|
|
|
| @@ -449,11 +414,8 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| } else {
|
| keyType = valueType = dynamicType.type;
|
| }
|
| - MapTypeMask mask = new MapTypeMask(type.type,
|
| - node,
|
| - element,
|
| - keyType,
|
| - valueType);
|
| + MapTypeMask mask =
|
| + new MapTypeMask(type.type, node, element, keyType, valueType);
|
|
|
| TypeInformation keyTypeInfo =
|
| new KeyInMapTypeInformation(currentMember, null);
|
| @@ -486,8 +448,8 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return info.isConcrete ? info.type : mask;
|
| }
|
|
|
| - TypeInformation allocateDiamondPhi(TypeInformation firstInput,
|
| - TypeInformation secondInput) {
|
| + TypeInformation allocateDiamondPhi(
|
| + TypeInformation firstInput, TypeInformation secondInput) {
|
| PhiElementTypeInformation result =
|
| new PhiElementTypeInformation(currentMember, null, false, null);
|
| result.addAssignment(firstInput);
|
| @@ -496,10 +458,8 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return result;
|
| }
|
|
|
| - PhiElementTypeInformation _addPhi(ast.Node node,
|
| - Local variable,
|
| - inputType,
|
| - bool isLoop) {
|
| + PhiElementTypeInformation _addPhi(
|
| + ast.Node node, Local variable, inputType, bool isLoop) {
|
| PhiElementTypeInformation result =
|
| new PhiElementTypeInformation(currentMember, node, isLoop, variable);
|
| allocatedTypes.add(result);
|
| @@ -507,9 +467,8 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return result;
|
| }
|
|
|
| - PhiElementTypeInformation allocatePhi(ast.Node node,
|
| - Local variable,
|
| - inputType) {
|
| + PhiElementTypeInformation allocatePhi(
|
| + ast.Node node, Local variable, inputType) {
|
| // Check if [inputType] is a phi for a local updated in
|
| // the try/catch block [node]. If it is, no need to allocate a new
|
| // phi.
|
| @@ -521,23 +480,20 @@ class TypeInformationSystem extends TypeSystem<TypeInformation> {
|
| return _addPhi(node, variable, inputType, false);
|
| }
|
|
|
| - PhiElementTypeInformation allocateLoopPhi(ast.Node node,
|
| - Local variable,
|
| - inputType) {
|
| + PhiElementTypeInformation allocateLoopPhi(
|
| + ast.Node node, Local variable, inputType) {
|
| return _addPhi(node, variable, inputType, true);
|
| }
|
|
|
| - TypeInformation simplifyPhi(ast.Node node,
|
| - Local variable,
|
| - PhiElementTypeInformation phiType) {
|
| + TypeInformation simplifyPhi(
|
| + ast.Node node, Local variable, PhiElementTypeInformation phiType) {
|
| assert(phiType.branchNode == node);
|
| if (phiType.assignments.length == 1) return phiType.assignments.first;
|
| return phiType;
|
| }
|
|
|
| PhiElementTypeInformation addPhiInput(Local variable,
|
| - PhiElementTypeInformation phiType,
|
| - TypeInformation newType) {
|
| + PhiElementTypeInformation phiType, TypeInformation newType) {
|
| phiType.addAssignment(newType);
|
| return phiType;
|
| }
|
| @@ -628,7 +584,7 @@ class TypeGraphInferrerEngine
|
| int addedInGraph = 0;
|
|
|
| TypeGraphInferrerEngine(Compiler compiler, this.mainElement)
|
| - : super(compiler, new TypeInformationSystem(compiler));
|
| + : super(compiler, new TypeInformationSystem(compiler));
|
|
|
| JavaScriptBackend get backend => compiler.backend;
|
| Annotations get annotations => backend.annotations;
|
| @@ -638,28 +594,26 @@ class TypeGraphInferrerEngine
|
| * A set of selector names that [List] implements, that we know return
|
| * their element type.
|
| */
|
| - final Set<Selector> returnsListElementTypeSet = new Set<Selector>.from(
|
| - <Selector>[
|
| - new Selector.getter(const PublicName('first')),
|
| - new Selector.getter(const PublicName('last')),
|
| - new Selector.getter(const PublicName('single')),
|
| - new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG),
|
| - new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG),
|
| - new Selector.index(),
|
| - new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG),
|
| - new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS)
|
| - ]);
|
| + final Set<Selector> returnsListElementTypeSet =
|
| + new Set<Selector>.from(<Selector>[
|
| + new Selector.getter(const PublicName('first')),
|
| + new Selector.getter(const PublicName('last')),
|
| + new Selector.getter(const PublicName('single')),
|
| + new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG),
|
| + new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG),
|
| + new Selector.index(),
|
| + new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG),
|
| + new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS)
|
| + ]);
|
|
|
| bool returnsListElementType(Selector selector, TypeMask mask) {
|
| return mask != null &&
|
| - mask.isContainer &&
|
| - returnsListElementTypeSet.contains(selector);
|
| + mask.isContainer &&
|
| + returnsListElementTypeSet.contains(selector);
|
| }
|
|
|
| bool returnsMapValueType(Selector selector, TypeMask mask) {
|
| - return mask != null &&
|
| - mask.isMap &&
|
| - selector.isIndex;
|
| + return mask != null && mask.isMap && selector.isIndex;
|
| }
|
|
|
| void analyzeListAndEnqueue(ListTypeInformation info) {
|
| @@ -745,18 +699,17 @@ class TypeGraphInferrerEngine
|
|
|
| // Trace closures to potentially infer argument types.
|
| types.allocatedClosures.forEach((info) {
|
| -
|
| - void trace(Iterable<FunctionElement> elements,
|
| - ClosureTracerVisitor tracer) {
|
| + void trace(
|
| + Iterable<FunctionElement> elements, ClosureTracerVisitor tracer) {
|
| tracer.run();
|
| if (!tracer.continueAnalyzing) {
|
| elements.forEach((FunctionElement e) {
|
| compiler.world.registerMightBePassedToApply(e);
|
| if (debug.VERBOSE) print("traced closure $e as ${true} (bail)");
|
| e.functionSignature.forEachParameter((parameter) {
|
| - types.getInferredTypeOf(parameter).giveUp(
|
| - this,
|
| - clearAssignments: false);
|
| + types
|
| + .getInferredTypeOf(parameter)
|
| + .giveUp(this, clearAssignments: false);
|
| });
|
| });
|
| bailedOutOn.addAll(elements);
|
| @@ -772,7 +725,8 @@ class TypeGraphInferrerEngine
|
| });
|
| if (tracer.tracedType.mightBePassedToFunctionApply) {
|
| compiler.world.registerMightBePassedToApply(e);
|
| - };
|
| + }
|
| + ;
|
| if (debug.VERBOSE) {
|
| print("traced closure $e as "
|
| "${compiler.world.getMightBePassedToApply(e)}");
|
| @@ -799,9 +753,8 @@ class TypeGraphInferrerEngine
|
| // 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<FunctionElement> elements =
|
| - new List<FunctionElement>.from(
|
| - info.callees.where((e) => e.isFunction));
|
| + Iterable<FunctionElement> elements = new List<FunctionElement>.from(
|
| + info.callees.where((e) => e.isFunction));
|
| trace(elements, new ClosureTracerVisitor(elements, info, this));
|
| }
|
| } else {
|
| @@ -832,23 +785,23 @@ class TypeGraphInferrerEngine
|
| if (debug.PRINT_SUMMARY) {
|
| types.allocatedLists.values.forEach((ListTypeInformation info) {
|
| print('${info.type} '
|
| - 'for ${info.originalType.allocationNode} '
|
| - 'at ${info.originalType.allocationElement} '
|
| - 'after ${info.refineCount}');
|
| + 'for ${info.originalType.allocationNode} '
|
| + 'at ${info.originalType.allocationElement} '
|
| + 'after ${info.refineCount}');
|
| });
|
| types.allocatedMaps.values.forEach((MapTypeInformation info) {
|
| print('${info.type} '
|
| - 'for ${info.originalType.allocationNode} '
|
| - 'at ${info.originalType.allocationElement} '
|
| - 'after ${info.refineCount}');
|
| + 'for ${info.originalType.allocationNode} '
|
| + 'at ${info.originalType.allocationElement} '
|
| + 'after ${info.refineCount}');
|
| });
|
| types.allocatedClosures.forEach((TypeInformation info) {
|
| if (info is ElementTypeInformation) {
|
| print('${types.getInferredSignatureOf(info.element)} for '
|
| - '${info.element}');
|
| + '${info.element}');
|
| } else if (info is ClosureTypeInformation) {
|
| print('${types.getInferredSignatureOf(info.element)} for '
|
| - '${info.element}');
|
| + '${info.element}');
|
| } else if (info is DynamicCallSiteTypeInformation) {
|
| for (Element target in info.targets) {
|
| if (target is FunctionElement) {
|
| @@ -900,8 +853,8 @@ class TypeGraphInferrerEngine
|
| if (type is! ListTypeInformation && type is! MapTypeInformation) {
|
| // For non-container types, the constant handler does
|
| // constant folding that could give more precise results.
|
| - ConstantValue value = compiler.backend.constants
|
| - .getConstantValueForVariable(element);
|
| + ConstantValue value =
|
| + compiler.backend.constants.getConstantValueForVariable(element);
|
| if (value != null) {
|
| if (value.isFunction) {
|
| FunctionConstantValue functionConstant = value;
|
| @@ -951,8 +904,7 @@ class TypeGraphInferrerEngine
|
| if (!info.inLoop) return;
|
| if (info is StaticCallSiteTypeInformation) {
|
| compiler.world.addFunctionCalledInLoop(info.calledElement);
|
| - } else if (info.mask != null &&
|
| - !info.mask.containsAll(compiler.world)) {
|
| + } else if (info.mask != null && !info.mask.containsAll(compiler.world)) {
|
| // For instance methods, we only register a selector called in a
|
| // loop if it is a typed selector, to avoid marking too many
|
| // methods as being called from within a loop. This cuts down
|
| @@ -1005,12 +957,9 @@ class TypeGraphInferrerEngine
|
| * wheter assignments must be added or removed. If [init] is false,
|
| * parameters are added to the work queue.
|
| */
|
| - void updateParameterAssignments(TypeInformation caller,
|
| - Element callee,
|
| - ArgumentsTypes arguments,
|
| - Selector selector,
|
| - TypeMask mask,
|
| - {bool remove, bool addToQueue: true}) {
|
| + void updateParameterAssignments(TypeInformation caller, Element callee,
|
| + ArgumentsTypes arguments, Selector selector, TypeMask mask,
|
| + {bool remove, bool addToQueue: true}) {
|
| if (callee.name == Identifiers.noSuchMethod_) return;
|
| if (callee.isField) {
|
| if (selector.isSetter) {
|
| @@ -1060,10 +1009,10 @@ class TypeGraphInferrerEngine
|
| TypeInformation type = visitingRequiredParameter
|
| ? arguments.positional[parameterIndex]
|
| : signature.optionalParametersAreNamed
|
| - ? arguments.named[parameter.name]
|
| - : parameterIndex < arguments.positional.length
|
| - ? arguments.positional[parameterIndex]
|
| - : null;
|
| + ? arguments.named[parameter.name]
|
| + : parameterIndex < arguments.positional.length
|
| + ? arguments.positional[parameterIndex]
|
| + : null;
|
| if (type == null) type = getDefaultTypeOfParameter(parameter);
|
| TypeInformation info = types.getInferredTypeOf(parameter);
|
| if (remove) {
|
| @@ -1083,8 +1032,8 @@ class TypeGraphInferrerEngine
|
| * a [PlaceholderTypeInformation], which will be replaced. All its uses are
|
| * updated.
|
| */
|
| - void setDefaultTypeOfParameter(ParameterElement parameter,
|
| - TypeInformation type) {
|
| + void setDefaultTypeOfParameter(
|
| + ParameterElement parameter, TypeInformation type) {
|
| assert(parameter.functionDeclaration.isImplementation);
|
| TypeInformation existing = defaultTypeOfParameter[parameter];
|
| defaultTypeOfParameter[parameter] = type;
|
| @@ -1141,20 +1090,17 @@ class TypeGraphInferrerEngine
|
| }
|
|
|
| TypeInformation returnTypeOfElement(Element element) {
|
| - if (element is !FunctionElement) return types.dynamicType;
|
| + if (element is! FunctionElement) return types.dynamicType;
|
| return types.getInferredTypeOf(element);
|
| }
|
|
|
| - void recordTypeOfFinalField(Spannable node,
|
| - Element analyzed,
|
| - Element element,
|
| - TypeInformation type) {
|
| + void recordTypeOfFinalField(
|
| + Spannable node, Element analyzed, Element element, TypeInformation type) {
|
| types.getInferredTypeOf(element).addAssignment(type);
|
| }
|
|
|
| - void recordTypeOfNonFinalField(Spannable node,
|
| - Element element,
|
| - TypeInformation type) {
|
| + void recordTypeOfNonFinalField(
|
| + Spannable node, Element element, TypeInformation type) {
|
| types.getInferredTypeOf(element).addAssignment(type);
|
| }
|
|
|
| @@ -1174,9 +1120,8 @@ class TypeGraphInferrerEngine
|
| if (info.assignments.isEmpty) info.addAssignment(type);
|
| }
|
|
|
| - TypeInformation addReturnTypeFor(Element element,
|
| - TypeInformation unused,
|
| - TypeInformation newType) {
|
| + TypeInformation addReturnTypeFor(
|
| + Element element, TypeInformation unused, TypeInformation newType) {
|
| TypeInformation type = types.getInferredTypeOf(element);
|
| // TODO(ngeoffray): Clean up. We do this check because
|
| // [SimpleTypesInferrer] deals with two different inferrers.
|
| @@ -1185,17 +1130,24 @@ class TypeGraphInferrerEngine
|
| return type;
|
| }
|
|
|
| - TypeInformation registerCalledElement(Spannable node,
|
| - Selector selector,
|
| - TypeMask mask,
|
| - Element caller,
|
| - Element callee,
|
| - ArgumentsTypes arguments,
|
| - SideEffects sideEffects,
|
| - bool inLoop) {
|
| + TypeInformation registerCalledElement(
|
| + Spannable node,
|
| + Selector selector,
|
| + TypeMask mask,
|
| + Element caller,
|
| + Element callee,
|
| + ArgumentsTypes arguments,
|
| + SideEffects sideEffects,
|
| + bool inLoop) {
|
| CallSiteTypeInformation info = new StaticCallSiteTypeInformation(
|
| - types.currentMember, node, caller, callee, selector, mask, arguments,
|
| - inLoop);
|
| + types.currentMember,
|
| + node,
|
| + caller,
|
| + callee,
|
| + selector,
|
| + mask,
|
| + arguments,
|
| + inLoop);
|
| // If this class has a 'call' method then we have essentially created a
|
| // closure here. Register it as such so that it is traced.
|
| if (selector != null && selector.isCall && callee.isConstructor) {
|
| @@ -1210,18 +1162,18 @@ class TypeGraphInferrerEngine
|
| return info;
|
| }
|
|
|
| - TypeInformation registerCalledSelector(ast.Node node,
|
| - Selector selector,
|
| - TypeMask mask,
|
| - TypeInformation receiverType,
|
| - Element caller,
|
| - ArgumentsTypes arguments,
|
| - SideEffects sideEffects,
|
| - bool inLoop) {
|
| + TypeInformation registerCalledSelector(
|
| + ast.Node node,
|
| + Selector selector,
|
| + TypeMask mask,
|
| + TypeInformation receiverType,
|
| + Element caller,
|
| + ArgumentsTypes arguments,
|
| + SideEffects sideEffects,
|
| + bool inLoop) {
|
| if (selector.isClosureCall) {
|
| - return registerCalledClosure(
|
| - node, selector, mask, receiverType,
|
| - caller, arguments, sideEffects, inLoop);
|
| + return registerCalledClosure(node, selector, mask, receiverType, caller,
|
| + arguments, sideEffects, inLoop);
|
| }
|
|
|
| compiler.world.allFunctions.filter(selector, mask).forEach((callee) {
|
| @@ -1229,8 +1181,14 @@ class TypeGraphInferrerEngine
|
| });
|
|
|
| CallSiteTypeInformation info = new DynamicCallSiteTypeInformation(
|
| - types.currentMember, node, caller, selector, mask,
|
| - receiverType, arguments, inLoop);
|
| + types.currentMember,
|
| + node,
|
| + caller,
|
| + selector,
|
| + mask,
|
| + receiverType,
|
| + arguments,
|
| + inLoop);
|
|
|
| info.addToGraph(this);
|
| allocatedCalls.add(info);
|
| @@ -1238,26 +1196,33 @@ class TypeGraphInferrerEngine
|
| }
|
|
|
| TypeInformation registerAwait(ast.Node node, TypeInformation argument) {
|
| - AwaitTypeInformation info = new AwaitTypeInformation(types.currentMember,
|
| - node);
|
| + AwaitTypeInformation info =
|
| + new AwaitTypeInformation(types.currentMember, node);
|
| info.addAssignment(argument);
|
| types.allocatedTypes.add(info);
|
| return info;
|
| }
|
|
|
| - TypeInformation registerCalledClosure(ast.Node node,
|
| - Selector selector,
|
| - TypeMask mask,
|
| - TypeInformation closure,
|
| - Element caller,
|
| - ArgumentsTypes arguments,
|
| - SideEffects sideEffects,
|
| - bool inLoop) {
|
| + TypeInformation registerCalledClosure(
|
| + ast.Node node,
|
| + Selector selector,
|
| + TypeMask mask,
|
| + TypeInformation closure,
|
| + Element caller,
|
| + ArgumentsTypes arguments,
|
| + SideEffects sideEffects,
|
| + bool inLoop) {
|
| sideEffects.setDependsOnSomething();
|
| sideEffects.setAllSideEffects();
|
| CallSiteTypeInformation info = new ClosureCallSiteTypeInformation(
|
| - types.currentMember, node, caller, selector, mask, closure, arguments,
|
| - inLoop);
|
| + types.currentMember,
|
| + node,
|
| + caller,
|
| + selector,
|
| + mask,
|
| + closure,
|
| + arguments,
|
| + inLoop);
|
| info.addToGraph(this);
|
| allocatedCalls.add(info);
|
| return info;
|
| @@ -1269,28 +1234,30 @@ class TypeGraphInferrerEngine
|
| Iterable<Element> sortResolvedElements() {
|
| int max = 0;
|
| Map<int, Setlet<Element>> methodSizes = new Map<int, Setlet<Element>>();
|
| - compiler.enqueuer.resolution.processedElements.forEach((AstElement element) {
|
| - // TODO(ngeoffray): Not sure why the resolver would put a null
|
| - // mapping.
|
| - if (!compiler.enqueuer.resolution.hasBeenProcessed(element)) return;
|
| - TreeElementMapping mapping = element.resolvedAst.elements;
|
| - element = element.implementation;
|
| - if (element.impliesType) return;
|
| - assert(invariant(element,
|
| - element.isField ||
|
| - element.isFunction ||
|
| - element.isConstructor ||
|
| - element.isGetter ||
|
| - element.isSetter,
|
| - message: '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 = mapping.getSelectorCount();
|
| - max = length > max ? length : max;
|
| - Setlet<Element> set = methodSizes.putIfAbsent(
|
| - length, () => new Setlet<Element>());
|
| - set.add(element);
|
| + compiler.enqueuer.resolution.processedElements
|
| + .forEach((AstElement element) {
|
| + // TODO(ngeoffray): Not sure why the resolver would put a null
|
| + // mapping.
|
| + if (!compiler.enqueuer.resolution.hasBeenProcessed(element)) return;
|
| + TreeElementMapping mapping = element.resolvedAst.elements;
|
| + element = element.implementation;
|
| + if (element.impliesType) return;
|
| + assert(invariant(
|
| + element,
|
| + element.isField ||
|
| + element.isFunction ||
|
| + element.isConstructor ||
|
| + element.isGetter ||
|
| + element.isSetter,
|
| + message: '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 = mapping.getSelectorCount();
|
| + max = length > max ? length : max;
|
| + Setlet<Element> set =
|
| + methodSizes.putIfAbsent(length, () => new Setlet<Element>());
|
| + set.add(element);
|
| });
|
|
|
| List<Element> result = <Element>[];
|
| @@ -1338,8 +1305,8 @@ class TypeGraphInferrerEngine
|
| /**
|
| * Returns the type of [element] when being called with [selector].
|
| */
|
| - TypeInformation typeOfElementWithSelector(Element element,
|
| - Selector selector) {
|
| + TypeInformation typeOfElementWithSelector(
|
| + Element element, Selector selector) {
|
| if (element.name == Identifiers.noSuchMethod_ &&
|
| selector.name != element.name) {
|
| // An invocation can resolve to a [noSuchMethod], in which case
|
| @@ -1426,8 +1393,7 @@ class TypeGraphInferrer implements TypesInferrer {
|
| if (inferrer.returnsMapValueType(selector, mask)) {
|
| MapTypeMask mapTypeMask = mask;
|
| TypeMask valueType = mapTypeMask.valueType;
|
| - return valueType == null ? compiler.typesTask.dynamicType
|
| - : valueType;
|
| + return valueType == null ? compiler.typesTask.dynamicType : valueType;
|
| }
|
|
|
| TypeMask result = const TypeMask.nonNullEmpty();
|
|
|