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

Side by Side Diff: pkg/lookup_map/lib/lookup_map.dart

Issue 1320503003: dart2js: add initial support for lookup-maps (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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) 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 lookup_map;
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 /// internally: if a key is not used elsewhere in the program, its entry can be
15 /// deleted from the map during compilation without changing the program's
16 /// behavior. Currently dart2js supports tree-shaking keys that are `Type`
17 /// literals, and any const expression that can only be created with a const
18 /// constructor. This means that primitives, Strings, and constant objects that
19 /// 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');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698