-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
registry.dart
154 lines (126 loc) · 5 KB
/
registry.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// 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 dart2js.js_emitter.program_builder;
class LibraryContents {
final List<ClassEntity> classes = <ClassEntity>[];
final List<MemberEntity> members = <MemberEntity>[];
}
/// Maps [LibraryEntity]s to their [ClassEntity]s and [MemberEntity]s.
///
/// Fundamentally, this class nicely encapsulates a
/// `Map<LibraryElement, Pair<List<ClassElement>, List<MemberElement>>>`.
///
/// There exists exactly one instance per [OutputUnit].
class LibrariesMap {
final Map<LibraryEntity, LibraryContents> _mapping =
<LibraryEntity, LibraryContents>{};
// It is very common to access the same library multiple times in a row, so
// we cache the last access.
LibraryEntity _lastLibrary;
LibraryContents _lastMapping;
/// A unique name representing this instance.
final String name;
final OutputUnit outputUnit;
LibrariesMap.main(this.outputUnit) : name = "";
LibrariesMap.deferred(this.outputUnit, this.name) {
assert(name != "");
}
LibraryContents _getMapping(LibraryEntity library) {
if (_lastLibrary != library) {
_lastLibrary = library;
_lastMapping = _mapping.putIfAbsent(library, () => new LibraryContents());
}
return _lastMapping;
}
void addClass(LibraryEntity library, ClassEntity element) {
_getMapping(library).classes.add(element);
}
void addMember(LibraryEntity library, MemberEntity element) {
_getMapping(library).members.add(element);
}
int get length => _mapping.length;
void forEach(
void f(LibraryEntity library, List<ClassEntity> classes,
List<MemberEntity> members)) {
_mapping.forEach((LibraryEntity library, LibraryContents mapping) {
f(library, mapping.classes, mapping.members);
});
}
}
/// Keeps track of all elements and holders.
///
/// This class assigns each registered element to its [LibrariesMap] (which are
/// in bijection with [OutputUnit]s).
///
/// Registered holders are assigned a name.
class Registry {
final DeferredLoadTask _deferredLoadTask;
final Sorter _sorter;
final Map<String, Holder> _holdersMap = <String, Holder>{};
final Map<OutputUnit, LibrariesMap> _deferredLibrariesMap =
<OutputUnit, LibrariesMap>{};
/// Cache for the last seen output unit.
OutputUnit _lastOutputUnit;
LibrariesMap _lastLibrariesMap;
Iterable<Holder> get holders => _holdersMap.values;
Iterable<LibrariesMap> get deferredLibrariesMap =>
_deferredLibrariesMap.values;
// Add one for the main libraries map.
int get librariesMapCount => _deferredLibrariesMap.length + 1;
LibrariesMap mainLibrariesMap;
Registry(this._deferredLoadTask, this._sorter);
OutputUnit get _mainOutputUnit => _deferredLoadTask.mainOutputUnit;
LibrariesMap _mapUnitToLibrariesMap(OutputUnit targetUnit) {
if (targetUnit == _lastOutputUnit) return _lastLibrariesMap;
LibrariesMap result = (targetUnit == _mainOutputUnit)
? mainLibrariesMap
: _deferredLibrariesMap[targetUnit];
assert(result != null);
_lastOutputUnit = targetUnit;
_lastLibrariesMap = result;
return result;
}
void registerOutputUnit(OutputUnit outputUnit) {
if (outputUnit == _mainOutputUnit) {
assert(mainLibrariesMap == null);
mainLibrariesMap =
new LibrariesMap.main(_deferredLoadTask.mainOutputUnit);
} else {
assert(!_deferredLibrariesMap.containsKey(outputUnit));
String name = outputUnit.name;
_deferredLibrariesMap[outputUnit] =
new LibrariesMap.deferred(outputUnit, name);
}
}
/// Adds all elements to their respective libraries in the correct
/// libraries map.
void registerClasses(OutputUnit outputUnit, Iterable<ClassEntity> elements) {
LibrariesMap targetLibrariesMap = _mapUnitToLibrariesMap(outputUnit);
for (ClassEntity element in _sorter.sortClasses(elements)) {
targetLibrariesMap.addClass(element.library, element);
}
}
/// Adds all elements to their respective libraries in the correct
/// libraries map.
void registerMembers(OutputUnit outputUnit, Iterable<MemberEntity> elements) {
LibrariesMap targetLibrariesMap = _mapUnitToLibrariesMap(outputUnit);
for (MemberEntity element in _sorter.sortMembers(elements)) {
targetLibrariesMap.addMember(element.library, element);
}
}
void registerConstant(OutputUnit outputUnit, ConstantValue constantValue) {
// Ignore for now.
}
Holder registerHolder(String name,
{bool isStaticStateHolder: false, bool isConstantsHolder: false}) {
assert(_holdersMap[name] == null ||
(_holdersMap[name].isStaticStateHolder == isStaticStateHolder &&
_holdersMap[name].isConstantsHolder == isConstantsHolder));
return _holdersMap.putIfAbsent(name, () {
return new Holder(name, _holdersMap.length,
isStaticStateHolder: isStaticStateHolder,
isConstantsHolder: isConstantsHolder);
});
}
}