blob: 7047fb00cab3cf12eaaa36ccd27db87074d1f365 [file] [log] [blame]
// Copyright (c) 2019, 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.
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/informative_data.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
/// The context of a linked bundle, with shared references.
class LinkedBundleContext {
final LinkedElementFactory elementFactory;
final LinkedNodeBundle _bundle;
final List<Reference> _references;
final Map<String, LinkedLibraryContext> libraryMap = {};
LinkedBundleContext(this.elementFactory, this._bundle)
: _references = List<Reference>(_bundle.references.name.length) {
for (var library in _bundle.libraries) {
var uriStr = library.uriStr;
var reference = elementFactory.rootReference.getChild(uriStr);
var libraryContext = LinkedLibraryContext(
this,
uriStr,
reference,
library,
);
libraryMap[uriStr] = libraryContext;
var unitRef = reference.getChild('@unit');
var units = library.units;
for (var unitIndex = 0; unitIndex < units.length; ++unitIndex) {
var unit = units[unitIndex];
var uriStr = unit.uriStr;
var reference = unitRef.getChild(uriStr);
var unitContext = LinkedUnitContext(
this,
libraryContext,
unitIndex,
unit.partUriStr,
uriStr,
reference,
unit.isSynthetic,
unit,
);
libraryContext.units.add(unitContext);
}
}
}
LinkedBundleContext.forAst(this.elementFactory, this._references)
: _bundle = null;
/// Return `true` if this bundle is being linked.
bool get isLinking => _bundle == null;
LinkedLibraryContext addLinkingLibrary(
String uriStr,
LinkedNodeLibraryBuilder data,
LinkInputLibrary inputLibrary,
) {
var uriStr = data.uriStr;
var reference = elementFactory.rootReference.getChild(uriStr);
var libraryContext = LinkedLibraryContext(this, uriStr, reference, data);
libraryMap[uriStr] = libraryContext;
var unitRef = reference.getChild('@unit');
var unitIndex = 0;
for (var inputUnit in inputLibrary.units) {
var source = inputUnit.source;
var uriStr = source != null ? '${source.uri}' : '';
var reference = unitRef.getChild(uriStr);
createInformativeData(inputUnit.unit);
libraryContext.units.add(
LinkedUnitContext(
this,
libraryContext,
unitIndex++,
inputUnit.partUriStr,
uriStr,
reference,
inputUnit.isSynthetic,
null,
unit: inputUnit.unit,
),
);
}
return libraryContext;
}
T elementOfIndex<T extends Element>(int index) {
var reference = referenceOfIndex(index);
return elementFactory.elementOfReference(reference);
}
List<T> elementsOfIndexes<T extends Element>(List<int> indexList) {
var result = List<T>(indexList.length);
for (var i = 0; i < indexList.length; ++i) {
var index = indexList[i];
result[i] = elementOfIndex(index);
}
return result;
}
Reference referenceOfIndex(int index) {
var reference = _references[index];
if (reference != null) return reference;
if (index == 0) {
reference = elementFactory.rootReference;
_references[index] = reference;
return reference;
}
var parentIndex = _bundle.references.parent[index];
var parent = referenceOfIndex(parentIndex);
var name = _bundle.references.name[index];
reference = parent.getChild(name);
_references[index] = reference;
return reference;
}
}
class LinkedLibraryContext {
final LinkedBundleContext context;
final String uriStr;
final Reference reference;
final LinkedNodeLibrary node;
final List<LinkedUnitContext> units = [];
LinkedLibraryContext(this.context, this.uriStr, this.reference, this.node);
LinkedUnitContext get definingUnit => units.first;
}