| Index: sdk/lib/_internal/compiler/implementation/inferrer/map_tracer.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/map_tracer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/map_tracer.dart
|
| deleted file mode 100644
|
| index 67c5c113adbbdb737c11d6b0e5241f2aae5666ab..0000000000000000000000000000000000000000
|
| --- a/sdk/lib/_internal/compiler/implementation/inferrer/map_tracer.dart
|
| +++ /dev/null
|
| @@ -1,124 +0,0 @@
|
| -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -part of type_graph_inferrer;
|
| -
|
| -Set<String> okMapSelectorsSet = new Set.from(
|
| - const <String>[
|
| - // From Object.
|
| - "==",
|
| - "hashCode",
|
| - "toString",
|
| - "noSuchMethod",
|
| - "runtimeType",
|
| - // From Map
|
| - "[]",
|
| - "isEmpty",
|
| - "isNotEmpty",
|
| - "keys",
|
| - "length",
|
| - "values",
|
| - "clear",
|
| - "containsKey",
|
| - "containsValue",
|
| - "forEach",
|
| - "remove"]);
|
| -
|
| -class MapTracerVisitor extends TracerVisitor<MapTypeInformation> {
|
| - // These lists are used to keep track of newly discovered assignments to
|
| - // the map. Note that elements at corresponding indices are expected to
|
| - // belong to the same assignment operation.
|
| - List<TypeInformation> keyAssignments = <TypeInformation>[];
|
| - List<TypeInformation> valueAssignments = <TypeInformation>[];
|
| - // This list is used to keep track of assignments of entire maps to
|
| - // this map.
|
| - List<MapTypeInformation> mapAssignments = <MapTypeInformation>[];
|
| -
|
| - MapTracerVisitor(tracedType, inferrer) : super(tracedType, inferrer);
|
| -
|
| - /**
|
| - * Returns [true] if the analysis completed successfully, [false]
|
| - * if it bailed out. In the former case, [keyAssignments] and
|
| - * [valueAssignments] hold a list of [TypeInformation] nodes that
|
| - * flow into the key and value types of this map.
|
| - */
|
| - bool run() {
|
| - analyze();
|
| - MapTypeInformation map = tracedType;
|
| - if (continueAnalyzing) {
|
| - map.addFlowsIntoTargets(flowsInto);
|
| - return true;
|
| - }
|
| - keyAssignments = valueAssignments = mapAssignments = null;
|
| - return false;
|
| - }
|
| -
|
| - visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
|
| - bailout('Passed to a closure');
|
| - }
|
| -
|
| - visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
|
| - super.visitStaticCallSiteTypeInformation(info);
|
| - Element called = info.calledElement;
|
| - if (called.isForeign(compiler.backend) && called.name == 'JS') {
|
| - bailout('Used in JS ${info.call}');
|
| - }
|
| - }
|
| -
|
| - visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
|
| - super.visitDynamicCallSiteTypeInformation(info);
|
| - Selector selector = info.selector;
|
| - String selectorName = selector.name;
|
| - if (currentUser == info.receiver) {
|
| - if (!okMapSelectorsSet.contains(selectorName)) {
|
| - if (selector.isCall) {
|
| - int positionalLength = info.arguments.positional.length;
|
| - if (selectorName == 'addAll') {
|
| - // All keys and values from the argument flow into
|
| - // the map.
|
| - TypeInformation map = info.arguments.positional[0];
|
| - if (map is MapTypeInformation) {
|
| - inferrer.analyzeMapAndEnqueue(map);
|
| - mapAssignments.add(map);
|
| - } else {
|
| - // If we could select a component from a [TypeInformation],
|
| - // like the keytype or valuetype in this case, we could
|
| - // propagate more here.
|
| - // TODO(herhut): implement selection on [TypeInformation].
|
| - bailout('Adding map with unknown typeinfo to current map');
|
| - }
|
| - } else if (selectorName == 'putIfAbsent') {
|
| - // The first argument is a new key, the result type of
|
| - // the second argument becomes a new value.
|
| - // Unfortunately, the type information does not
|
| - // explicitly track the return type, yet, so we have
|
| - // to go to dynamic.
|
| - // TODO(herhut,16507): Use return type of closure in
|
| - // Map.putIfAbsent.
|
| - keyAssignments.add(info.arguments.positional[0]);
|
| - valueAssignments.add(inferrer.types.dynamicType);
|
| - } else {
|
| - // It would be nice to handle [Map.keys] and [Map.values], too.
|
| - // However, currently those calls do not trigger the creation
|
| - // of a [ListTypeInformation], so I have nowhere to propagate
|
| - // that information.
|
| - // TODO(herhut): add support for Map.keys and Map.values.
|
| - bailout('Map used in a not-ok selector [$selectorName]');
|
| - return;
|
| - }
|
| - } else if (selector.isIndexSet) {
|
| - keyAssignments.add(info.arguments.positional[0]);
|
| - valueAssignments.add(info.arguments.positional[1]);
|
| - } else if (!selector.isIndex) {
|
| - bailout('Map used in a not-ok selector [$selectorName]');
|
| - return;
|
| - }
|
| - }
|
| - } else if (selector.isCall &&
|
| - !info.targets.every((element) => element.isFunction)) {
|
| - bailout('Passed to a closure');
|
| - return;
|
| - }
|
| - }
|
| -}
|
|
|