Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/inferrer/map_tracer.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of type_graph_inferrer;
6
7 Set<String> okMapSelectorsSet = new Set.from(
8 const <String>[
9 // From Object.
10 "==",
11 "hashCode",
12 "toString",
13 "noSuchMethod",
14 "runtimeType",
15 // From Map
16 "[]",
17 "isEmpty",
18 "isNotEmpty",
19 "keys",
20 "length",
21 "values",
22 "clear",
23 "containsKey",
24 "containsValue",
25 "forEach",
26 "remove"]);
27
28 class MapTracerVisitor extends TracerVisitor<MapTypeInformation> {
29 // These lists are used to keep track of newly discovered assignments to
30 // the map. Note that elements at corresponding indices are expected to
31 // belong to the same assignment operation.
32 List<TypeInformation> keyAssignments = <TypeInformation>[];
33 List<TypeInformation> valueAssignments = <TypeInformation>[];
34 // This list is used to keep track of assignments of entire maps to
35 // this map.
36 List<MapTypeInformation> mapAssignments = <MapTypeInformation>[];
37
38 MapTracerVisitor(tracedType, inferrer) : super(tracedType, inferrer);
39
40 /**
41 * Returns [true] if the analysis completed successfully, [false]
42 * if it bailed out. In the former case, [keyAssignments] and
43 * [valueAssignments] hold a list of [TypeInformation] nodes that
44 * flow into the key and value types of this map.
45 */
46 bool run() {
47 analyze();
48 MapTypeInformation map = tracedType;
49 if (continueAnalyzing) {
50 map.addFlowsIntoTargets(flowsInto);
51 return true;
52 }
53 keyAssignments = valueAssignments = mapAssignments = null;
54 return false;
55 }
56
57 visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
58 bailout('Passed to a closure');
59 }
60
61 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
62 super.visitStaticCallSiteTypeInformation(info);
63 Element called = info.calledElement;
64 if (called.isForeign(compiler.backend) && called.name == 'JS') {
65 bailout('Used in JS ${info.call}');
66 }
67 }
68
69 visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
70 super.visitDynamicCallSiteTypeInformation(info);
71 Selector selector = info.selector;
72 String selectorName = selector.name;
73 if (currentUser == info.receiver) {
74 if (!okMapSelectorsSet.contains(selectorName)) {
75 if (selector.isCall) {
76 int positionalLength = info.arguments.positional.length;
77 if (selectorName == 'addAll') {
78 // All keys and values from the argument flow into
79 // the map.
80 TypeInformation map = info.arguments.positional[0];
81 if (map is MapTypeInformation) {
82 inferrer.analyzeMapAndEnqueue(map);
83 mapAssignments.add(map);
84 } else {
85 // If we could select a component from a [TypeInformation],
86 // like the keytype or valuetype in this case, we could
87 // propagate more here.
88 // TODO(herhut): implement selection on [TypeInformation].
89 bailout('Adding map with unknown typeinfo to current map');
90 }
91 } else if (selectorName == 'putIfAbsent') {
92 // The first argument is a new key, the result type of
93 // the second argument becomes a new value.
94 // Unfortunately, the type information does not
95 // explicitly track the return type, yet, so we have
96 // to go to dynamic.
97 // TODO(herhut,16507): Use return type of closure in
98 // Map.putIfAbsent.
99 keyAssignments.add(info.arguments.positional[0]);
100 valueAssignments.add(inferrer.types.dynamicType);
101 } else {
102 // It would be nice to handle [Map.keys] and [Map.values], too.
103 // However, currently those calls do not trigger the creation
104 // of a [ListTypeInformation], so I have nowhere to propagate
105 // that information.
106 // TODO(herhut): add support for Map.keys and Map.values.
107 bailout('Map used in a not-ok selector [$selectorName]');
108 return;
109 }
110 } else if (selector.isIndexSet) {
111 keyAssignments.add(info.arguments.positional[0]);
112 valueAssignments.add(info.arguments.positional[1]);
113 } else if (!selector.isIndex) {
114 bailout('Map used in a not-ok selector [$selectorName]');
115 return;
116 }
117 }
118 } else if (selector.isCall &&
119 !info.targets.every((element) => element.isFunction)) {
120 bailout('Passed to a closure');
121 return;
122 }
123 }
124 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698