OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2015, 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 /// Defines [LookupMap], a simple map that can be optimized by dart2js. | |
6 library type_lookup_map; | |
sra1
2015/09/02 00:55:25
Do we want 'type' in the library name?
Siggi Cherem (dart-lang)
2015/09/03 00:44:30
oops - removed. this was the old name before I dec
| |
7 | |
8 /// [LookupMap] is a simple, but very restricted map. The map can only hold | |
9 /// constant keys and the only way to use the map is to retrieve values with a | |
10 /// key you already have. Expect for lookup, any other operation in [Map] (like | |
11 /// forEach, keys, values, length, etc) is not available. | |
12 /// | |
13 /// Constant [LookupMap]s are understood by dart2js and can be tree-shaken | |
14 /// internaly: if a key is not used elsewhere in the program, its entry can be | |
sra1
2015/09/02 00:55:25
internally
Siggi Cherem (dart-lang)
2015/09/03 00:44:30
Done.
| |
15 /// deleted from the map during compilation without changing the program | |
16 /// semantics in any visible way. Currently dart2js supports tree-shaking keys | |
sra1
2015/09/02 00:55:25
changing the program semantics in any visible way
herhut
2015/09/02 12:59:57
That is even nicer...
Siggi Cherem (dart-lang)
2015/09/03 00:44:30
Done.
| |
17 /// that are `Type` literals, and any const expression that can only be created | |
18 /// with a const constructor. This means that primitives, Strings, and constant | |
19 /// objects that override the `==` operator cannot be tree-shaken. | |
20 /// | |
21 /// Note: [LookupMap] is unlikely going to be useful for individual developers | |
22 /// writing code by hand. It is mainly intended as a helper utility for | |
23 /// frameworks that need to autogenerate data and associate it with a type in | |
24 /// the program. For example, this can be used by a dependency injection system | |
25 /// to record how to create instances of a given type. A dependency injection | |
26 /// framework can store in a [LookupMap] all the information it needs for every | |
27 /// injectable type in every library and package. When compiling a specific | |
28 /// application, dart2js can tree-shake the data of types that are not used by | |
29 /// the application. Similarly, this can also be used by | |
30 /// serialization/deserialization packages that can store in a [LookupMap] the | |
31 /// deserialization logic for a given type. | |
32 class LookupMap<K, V> { | |
33 /// The key for [LookupMap]s with a single key/value pair. | |
34 final K _key; | |
35 | |
36 /// The value for [LookupMap]s with a single key/value pair. | |
37 final V _value; | |
38 | |
39 /// List of alternating key-value pairs in the map. | |
40 final List _entries; | |
41 | |
42 /// Other maps to which this map delegates lookup operations if the key is not | |
43 /// found on [entries]. See [LookupMap]'s constructor for details. | |
44 final List<LookupMap<K, V>> _nestedMaps; | |
45 | |
46 /// Creates a lookup-map given a list of key-value pair [entries], and | |
47 /// optionally additional entries from other [LookupMap]s. | |
48 /// | |
49 /// When doing a lookup, if the key is not found on [entries]. The lookup will | |
50 /// be performed in reverse order of the list of [nestedMaps], so a later | |
51 /// entry for a key shadows previous entries. For example, in: | |
52 /// | |
53 /// const map = const LookupMap(const [A, 1], | |
54 /// const [const LookupMap(const [A, 2, B, 4]), | |
55 /// const LookupMap(const [A, 3, B, 5])); | |
56 /// | |
57 /// `map[A]` returns `1` and `map[B]` returns `5`. | |
58 /// | |
59 /// Note: in the future we expect to change [entries] to be a const map | |
60 /// instead of a list of key-value pairs. | |
61 // TODO(sigmund): make entries a map once we fix TypeImpl.== (issue #17207). | |
62 const LookupMap(List entries, [List<LookupMap<K, V>> nestedMaps = const []]) | |
63 : _key = null, _value = null, _entries = entries, _nestedMaps = nestedMaps; | |
64 | |
65 /// Creates a lookup map with a single key-value pair. | |
66 const LookupMap.pair(K key, V value) | |
67 : _key = key, _value = value, _entries = const [], _nestedMaps = const []; | |
68 | |
69 /// Return the data corresponding to [key]. | |
70 V operator[](K key) { | |
71 var map = _flatMap[this]; | |
72 if (map == null) { | |
73 map = {}; | |
74 _addEntriesTo(map); | |
75 _flatMap[this] = map; | |
76 } | |
77 return map[key]; | |
78 } | |
79 | |
80 /// Add to [map] entries from [nestedMaps] and from [entries] according to the | |
81 /// precedense order described in [nestedMaps]. | |
82 _addEntriesTo(Map map) { | |
83 _nestedMaps.forEach((m) => m._addEntriesTo(map)); | |
84 for (var i = 0; i < _entries.length; i += 2) { | |
85 map[_entries[i]] = _entries[i + 1]; | |
86 } | |
87 if (_key != null) map[_key] = _value; | |
88 } | |
89 } | |
90 | |
91 /// An expando that stores a flatten version of a [LookupMap], this is | |
92 /// computed and stored the first time the map is accessed. | |
93 final _flatMap = new Expando('_flat_map'); | |
OLD | NEW |