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

Side by Side Diff: tool/input_sdk/private/constant_map.dart

Issue 1963723003: update Map (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 7 months 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
OLDNEW
(Empty)
1 // Copyright (c) 2012, 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 dart._js_helper;
6
7 class ConstantMapView<K, V> extends UnmodifiableMapView<K, V>
8 implements ConstantMap<K, V> {
9 ConstantMapView(Map<K, V> base) : super(base);
10 }
11
12 abstract class ConstantMap<K, V> implements Map<K, V> {
13 // Used to create unmodifiable maps from other maps.
14 factory ConstantMap.from(Map other) {
15 List keys = other.keys.toList();
16 bool allStrings = true;
17 for (var k in keys) {
18 if (k is! String) {
19 allStrings = false;
20 break;
21 }
22 }
23 if (allStrings) {
24 bool containsProto = false;
25 var protoValue = null;
26 var object = JS('=Object', '{}');
27 int length = 0;
28 for (var k in keys) {
29 var v = other[k];
30 if (k != "__proto__") {
31 if (!jsHasOwnProperty(object, k as String)) length++;
32 JS("void", "#[#] = #", object, k, v);
33 } else {
34 containsProto = true;
35 protoValue = v;
36 }
37 }
38 if (containsProto) {
39 length++;
40 return new ConstantProtoMap<K, V>._(length, object, keys, protoValue);
41 }
42 return new ConstantStringMap<K, V>._(length, object, keys);
43 }
44 // TODO(lrn): Make a proper unmodifiable map implementation.
45 return new ConstantMapView<K, V>(new Map.from(other));
46 }
47
48 const ConstantMap._();
49
50 bool get isEmpty => length == 0;
51
52 bool get isNotEmpty => !isEmpty;
53
54 String toString() => Maps.mapToString(this);
55
56 static _throwUnmodifiable() {
57 throw new UnsupportedError("Cannot modify unmodifiable Map");
58 }
59 void operator []=(K key, V val) => _throwUnmodifiable();
60 V putIfAbsent(K key, V ifAbsent()) => _throwUnmodifiable();
61 V remove(Object key) => _throwUnmodifiable();
62 void clear() => _throwUnmodifiable();
63 void addAll(Map<K, V> other) => _throwUnmodifiable();
64 }
65
66 class ConstantStringMap<K, V> extends ConstantMap<K, V> {
67
68 // This constructor is not used for actual compile-time constants.
69 // The instantiation of constant maps is shortcut by the compiler.
70 const ConstantStringMap._(this._length, this._jsObject, this._keys)
71 : super._();
72
73 // TODO(18131): Ensure type inference knows the precise types of the fields.
74 final int _length;
75 // A constant map is backed by a JavaScript object.
76 final _jsObject;
77 final List<K> _keys;
78
79 int get length => JS('JSUInt31', '#', _length);
80 List get _keysArray => JS('JSUnmodifiableArray', '#', _keys);
81
82 bool containsValue(Object needle) {
83 return values.any((V value) => value == needle);
84 }
85
86 bool containsKey(Object key) {
87 if (key is! String) return false;
88 if ('__proto__' == key) return false;
89 return jsHasOwnProperty(_jsObject, key);
90 }
91
92 V operator [](Object key) {
93 if (!containsKey(key)) return null;
94 return _fetch(key);
95 }
96
97 // [_fetch] is the indexer for keys for which `containsKey(key)` is true.
98 _fetch(key) => jsPropertyAccess(_jsObject, key);
99
100 void forEach(void f(K key, V value)) {
101 // Use a JS 'cast' to get efficient loop. Type inferrence doesn't get this
102 // since constant map representation is chosen after type inferrence and the
103 // instantiation is shortcut by the compiler.
104 var keys = _keysArray;
105 for (int i = 0; i < keys.length; i++) {
106 var key = keys[i];
107 f(key, _fetch(key));
108 }
109 }
110
111 Iterable<K> get keys {
112 return new _ConstantMapKeyIterable<K>(this);
113 }
114
115 Iterable<V> get values {
116 return new MappedIterable<K, V>(_keysArray, (key) => _fetch(key));
117 }
118 }
119
120 class ConstantProtoMap<K, V> extends ConstantStringMap<K, V> {
121 // This constructor is not used. The instantiation is shortcut by the
122 // compiler. It is here to make the uninitialized final fields legal.
123 ConstantProtoMap._(length, jsObject, keys, this._protoValue)
124 : super._(length, jsObject, keys);
125
126 final V _protoValue;
127
128 bool containsKey(Object key) {
129 if (key is! String) return false;
130 if ('__proto__' == key) return true;
131 return jsHasOwnProperty(_jsObject, key);
132 }
133
134 _fetch(key) =>
135 '__proto__' == key ? _protoValue : jsPropertyAccess(_jsObject, key);
136 }
137
138 class _ConstantMapKeyIterable<K> extends Iterable<K> {
139 ConstantStringMap<K, dynamic> _map;
140 _ConstantMapKeyIterable(this._map);
141
142 Iterator<K> get iterator => _map._keysArray.iterator;
143
144 int get length => _map._keysArray.length;
145 }
146
147 class GeneralConstantMap<K, V> extends ConstantMap<K, V> {
148 // This constructor is not used. The instantiation is shortcut by the
149 // compiler. It is here to make the uninitialized final fields legal.
150 GeneralConstantMap(this._jsData) : super._();
151
152 // [_jsData] holds a key-value pair list.
153 final _jsData;
154
155 // We cannot create the backing map on creation since hashCode interceptors
156 // have not been defined when constants are created.
157 Map<K, V> _getMap() {
158 LinkedHashMap<K, V> backingMap = JS('LinkedHashMap|Null', r'#.$map', this);
159 if (backingMap == null) {
160 backingMap = new JsLinkedHashMap<K, V>();
161 fillLiteralMap(_jsData, backingMap);
162 JS('', r'#.$map = #', this, backingMap);
163 }
164 return backingMap;
165 }
166
167 bool containsValue(Object needle) {
168 return _getMap().containsValue(needle);
169 }
170
171 bool containsKey(Object key) {
172 return _getMap().containsKey(key);
173 }
174
175 V operator [](Object key) {
176 return _getMap()[key];
177 }
178
179 void forEach(void f(K key, V value)) {
180 _getMap().forEach(f);
181 }
182
183 Iterable<K> get keys {
184 return _getMap().keys;
185 }
186
187 Iterable<V> get values {
188 return _getMap().values;
189 }
190
191 int get length => _getMap().length;
192 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698