Skip to content

Remove driver and session from PackageGraph #2204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions lib/src/model/library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type_system.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:dartdoc/src/model/model.dart';
Expand Down Expand Up @@ -56,20 +55,22 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
List<TopLevelVariable> _variables;
List<Element> _exportedAndLocalElements;
String _name;
final String _restoredUri;

factory Library(LibraryElement element, PackageGraph packageGraph) {
return packageGraph.findButDoNotCreateLibraryFor(element);
}

Library.fromLibraryResult(ResolvedLibraryResult libraryResult,
Library.fromLibraryResult(DartDocResolvedLibrary resolvedLibrary,
PackageGraph packageGraph, this._package)
: super(libraryResult.element, null, packageGraph, null) {
: _restoredUri = resolvedLibrary.restoredUri,
super(resolvedLibrary.result.element, null, packageGraph, null) {
if (element == null) throw ArgumentError.notNull('element');

// Initialize [packageGraph]'s cache of ModelNodes for relevant
// elements in this library.
var _compilationUnitMap = <String, CompilationUnit>{};
_compilationUnitMap.addEntries(libraryResult.units
_compilationUnitMap.addEntries(resolvedLibrary.result.units
.map((ResolvedUnitResult u) => MapEntry(u.path, u.unit)));
_HashableChildLibraryElementVisitor((Element e) =>
packageGraph.populateModelNodeFor(e, _compilationUnitMap))
Expand Down Expand Up @@ -414,7 +415,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
/// 'lib') are the same, but this will include slashes and possibly colons
/// for anonymous libraries in subdirectories or other packages.
String get nameFromPath {
_nameFromPath ??= getNameFromPath(element, packageGraph.driver, package);
_nameFromPath ??= _getNameFromPath(element, package, _restoredUri);
return _nameFromPath;
}

Expand Down Expand Up @@ -502,14 +503,9 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
/// path components; this function only strips the package prefix if the
/// library is part of the default package or if it is being documented
/// remotely.
static String getNameFromPath(
LibraryElement element, AnalysisDriver driver, Package package) {
String name;
if (element.source.uri.toString().startsWith('dart:')) {
name = element.source.uri.toString();
} else {
name = driver.sourceFactory.restoreUri(element.source).toString();
}
static String _getNameFromPath(
LibraryElement element, Package package, String restoredUri) {
var name = restoredUri;
PackageMeta hidePackage;
if (package.documentedWhere == DocumentLocation.remote) {
hidePackage = package.packageMeta;
Expand Down
35 changes: 30 additions & 5 deletions lib/src/model/package_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class PackageBuilder {
var rendererFactory = RendererFactory.forFormat(config.format);

var newGraph = PackageGraph.UninitializedPackageGraph(
config, driver, sdk, hasEmbedderSdkFiles, rendererFactory);
config, sdk, hasEmbedderSdkFiles, rendererFactory);
await getLibraries(newGraph);
await newGraph.initializePackageGraph();
return newGraph;
Expand Down Expand Up @@ -187,7 +187,7 @@ class PackageBuilder {

/// Parse a single library at [filePath] using the current analysis driver.
/// If [filePath] is not a library, returns null.
Future<ResolvedLibraryResult> processLibrary(String filePath) async {
Future<DartDocResolvedLibrary> processLibrary(String filePath) async {
var name = filePath;

if (name.startsWith(directoryCurrentPath)) {
Expand Down Expand Up @@ -215,7 +215,15 @@ class PackageBuilder {
if (sourceKind != SourceKind.PART) {
// Loading libraryElements from part files works, but is painfully slow
// and creates many duplicates.
return await driver.currentSession.getResolvedLibrary(source.fullName);
final library =
await driver.currentSession.getResolvedLibrary(source.fullName);
final libraryElement = library.element;
var restoredUri = libraryElement.source.uri.toString();
if (!restoredUri.startsWith('dart:')) {
restoredUri =
driver.sourceFactory.restoreUri(library.element.source).toString();
}
return DartDocResolvedLibrary(library, restoredUri);
}
return null;
}
Expand All @@ -235,7 +243,7 @@ class PackageBuilder {
/// the callback more than once with the same [LibraryElement].
/// Adds [LibraryElement]s found to that parameter.
Future<void> _parseLibraries(
void Function(ResolvedLibraryResult) libraryAdder,
void Function(DartDocResolvedLibrary) libraryAdder,
Set<LibraryElement> libraries,
Set<String> files,
[bool Function(LibraryElement) isLibraryIncluded]) async {
Expand All @@ -246,7 +254,7 @@ class PackageBuilder {
lastPass = _packageMetasForFiles(files);

// Be careful here not to accidentally stack up multiple
// ResolvedLibraryResults, as those eat our heap.
// DartDocResolvedLibrarys, as those eat our heap.
for (var f in files) {
logProgress(f);
var r = await processLibrary(f);
Expand Down Expand Up @@ -461,3 +469,20 @@ class PackageWithoutSdkResolver extends UriResolver {
return null;
}
}

/// Contains the [ResolvedLibraryResult] and any additional information about
/// the library coming from [AnalysisDriver].
///
/// Prefer to populate this class with more information rather than passing
/// [AnalysisDriver] or [AnalysisSession] down to [PackageGraph]. The graph
/// object is reachable by many DartDoc model objects and there's no guarantee
/// that there's a valid [AnalysisDriver] in every environment dartdoc runs.
class DartDocResolvedLibrary {
final ResolvedLibraryResult result;
final String restoredUri;

DartDocResolvedLibrary(this.result, this.restoredUri);

LibraryElement get element => result.element;
LibraryElement get library => result.element.library;
}
38 changes: 16 additions & 22 deletions lib/src/model/package_graph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@

import 'dart:async';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
Expand All @@ -24,10 +21,9 @@ import 'package:dartdoc/src/tuple.dart';
import 'package:dartdoc/src/warnings.dart';

class PackageGraph {
PackageGraph.UninitializedPackageGraph(this.config, this.driver, this.sdk,
this.hasEmbedderSdk, this.rendererFactory)
: packageMeta = config.topLevelPackageMeta,
session = driver.currentSession {
PackageGraph.UninitializedPackageGraph(
this.config, this.sdk, this.hasEmbedderSdk, this.rendererFactory)
: packageMeta = config.topLevelPackageMeta {
_packageWarningCounter = PackageWarningCounter(this);
// Make sure the default package exists, even if it has no libraries.
// This can happen for packages that only contain embedder SDKs.
Expand All @@ -39,23 +35,23 @@ class PackageGraph {
/// Libraries added in this manner are assumed to be part of documented
/// packages, even if includes or embedder.yaml files cause these to
/// span packages.
void addLibraryToGraph(ResolvedLibraryResult result) {
void addLibraryToGraph(DartDocResolvedLibrary resolvedLibrary) {
assert(!allLibrariesAdded);
var element = result.element;
var element = resolvedLibrary.element;
var packageMeta = PackageMeta.fromElement(element, config.sdkDir);
var lib = Library.fromLibraryResult(
result, this, Package.fromPackageMeta(packageMeta, this));
resolvedLibrary, this, Package.fromPackageMeta(packageMeta, this));
packageMap[packageMeta.name].libraries.add(lib);
allLibraries[element] = lib;
}

/// Call during initialization to add a library possibly containing
/// special/non-documented elements to this [PackageGraph]. Must be called
/// after any normal libraries.
void addSpecialLibraryToGraph(ResolvedLibraryResult result) {
void addSpecialLibraryToGraph(DartDocResolvedLibrary resolvedLibrary) {
allLibrariesAdded = true;
assert(!_localDocumentationBuilt);
findOrCreateLibraryFor(result);
findOrCreateLibraryFor(resolvedLibrary);
}

/// Call after all libraries are added.
Expand Down Expand Up @@ -234,9 +230,6 @@ class PackageGraph {
/// Map of package name to Package.
final Map<String, Package> packageMap = {};

/// TODO(brianwilkerson) Replace the driver with the session.
final AnalysisDriver driver;
final AnalysisSession session;
final DartSdk sdk;

Map<Source, SdkLibrary> _sdkLibrarySources;
Expand Down Expand Up @@ -829,22 +822,23 @@ class PackageGraph {
/// This is used when we might need a Library object that isn't actually
/// a documentation entry point (for elements that have no Library within the
/// set of canonical Libraries).
Library findOrCreateLibraryFor(ResolvedLibraryResult result) {
Library findOrCreateLibraryFor(DartDocResolvedLibrary resolvedLibrary) {
final elementLibrary = resolvedLibrary.library;
// This is just a cache to avoid creating lots of libraries over and over.
if (allLibraries.containsKey(result.element.library)) {
return allLibraries[result.element.library];
if (allLibraries.containsKey(elementLibrary)) {
return allLibraries[elementLibrary];
}
// can be null if e is for dynamic
if (result.element.library == null) {
if (elementLibrary == null) {
return null;
}
var foundLibrary = Library.fromLibraryResult(
result,
resolvedLibrary,
this,
Package.fromPackageMeta(
PackageMeta.fromElement(result.element.library, config.sdkDir),
PackageMeta.fromElement(elementLibrary, config.sdkDir),
packageGraph));
allLibraries[result.element.library] = foundLibrary;
allLibraries[elementLibrary] = foundLibrary;
return foundLibrary;
}

Expand Down