blob: cc8b2302aad3947b73b0dd3de9413e205278dba9 [file] [log] [blame]
// 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.new_js_emitter.emitter;
/// A Fragment maps [LibraryElement]s to their [Element]s.
///
/// Fundamentally, this class is a `Map<LibraryElement, List<Element>>`.
class Fragment {
final Map<LibraryElement, List<Element>> _mapping = <LibraryElement,
List<Element>>{};
// It is very common to access the same library multiple times in a row, so
// we cache the last access.
LibraryElement _lastLibrary;
List<Element> _lastElements;
void add(LibraryElement library, Element element) {
if (_lastLibrary != library) {
_lastLibrary = library;
_lastElements = _mapping.putIfAbsent(library, () => <Element>[]);
}
_lastElements.add(element);
}
int get length => _mapping.length;
void forEach(void f(LibraryElement library, List<Element> elements)) {
_mapping.forEach(f);
}
}
class Registry {
final DeferredLoadTask _deferredLoadTask;
final Map<String, Holder> _holdersMap = <String, Holder>{};
final Map<OutputUnit, Fragment> _fragmentsMap = <OutputUnit, Fragment>{};
Iterable<Holder> get holders => _holdersMap.values;
Iterable<Fragment> get deferredFragments => _fragmentsMap.values.skip(1);
int get fragmentCount => _fragmentsMap.length;
/// A fastpath for `_libraryElements[_mainOutputUnit]`.
final Fragment mainFragment = new Fragment();
Registry(this._deferredLoadTask) {
_fragmentsMap[_mainOutputUnit] = mainFragment;
}
bool get _isProgramSplit => _deferredLoadTask.isProgramSplit;
OutputUnit get _mainOutputUnit => _deferredLoadTask.mainOutputUnit;
Fragment _computeTargetFragment(Element element) {
if (!_isProgramSplit) return mainFragment;
OutputUnit targetUnit = _deferredLoadTask.outputUnitForElement(element);
return (targetUnit == _mainOutputUnit)
? mainFragment
: _fragmentsMap.putIfAbsent(targetUnit, () => new Fragment());
}
/// Adds the element to the list of elements of the library in the right
/// fragment.
void registerElement(Element element) {
_computeTargetFragment(element).add(element.library, element);
}
Holder registerHolder(String name) {
return _holdersMap.putIfAbsent(
name,
() => new Holder(name, _holdersMap.length));
}
}