Skip to content

Commit e4e16af

Browse files
jcollins-gscheglov
andauthored
Port to AnalysisContextCollection (#2433)
* Switch to AnalysisContextCollection. * Add some debug output. * add more debug data * check for null * add more debug output * fix lints * hack for C: * retry with C: or c: * tweak * restore processLibrary() * fix hints * revert restore * patch up to work on smoke test * fix documentation_comment_test * Fix broken recursion in _parseLibraries * tweaks * Fix dart: name mangling * fix windows? And cleanup * dartfmt/lint * reenable includeExternal test * Update pubspec for analyzer 0.41 * disable documentation_comment_test for windows (#2446) * Cleanup * cleanups * html_generator_test also impacted by #2446 * one more test to disable * Disable one more test * package_test Co-authored-by: Konstantin Shcheglov <[email protected]>
1 parent d152fcd commit e4e16af

File tree

7 files changed

+892
-979
lines changed

7 files changed

+892
-979
lines changed

lib/src/model/library.dart

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,27 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
427427

428428
@override
429429
String get name {
430-
_name ??= _getLibraryName(element);
430+
if (_name == null) {
431+
var source = element.source;
432+
433+
if (source.uri.isScheme('dart')) {
434+
// There are inconsistencies in library naming + URIs for the dart
435+
// internal libraries; rationalize them here.
436+
if (source.uri.toString().contains('/')) {
437+
_name = element.name.replaceFirst('dart.', 'dart:');
438+
} else {
439+
_name = source.uri.toString();
440+
}
441+
} else if (element.name != null && element.name.isNotEmpty) {
442+
_name = element.name;
443+
} else {
444+
_name = path.basename(source.fullName);
445+
if (_name.endsWith('.dart')) {
446+
_name = _name.substring(0, _name.length - '.dart'.length);
447+
}
448+
}
449+
}
450+
431451
return _name;
432452
}
433453

@@ -555,31 +575,6 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
555575
return name;
556576
}
557577

558-
static String _getLibraryName(LibraryElement element) {
559-
var source = element.source;
560-
561-
if (source.uri.isScheme('dart')) {
562-
return '${source.uri}';
563-
}
564-
565-
var name = element.name;
566-
if (name != null && name.isNotEmpty) {
567-
return name;
568-
}
569-
570-
name = path.basename(source.fullName);
571-
if (name.endsWith('.dart')) {
572-
name = name.substring(0, name.length - '.dart'.length);
573-
}
574-
return name;
575-
}
576-
577-
@Deprecated(
578-
'Public method intended to be private; will be removed as early as '
579-
'Dartdoc 1.0.0')
580-
static String getLibraryName(LibraryElement element) =>
581-
_getLibraryName(element);
582-
583578
/*late final*/ HashMap<String, Set<ModelElement>> _modelElementsNameMap;
584579

585580
/// Map of [fullyQualifiedNameWithoutLibrary] to all matching [ModelElement]s

lib/src/model/package_builder.dart

Lines changed: 46 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,19 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'package:analyzer/dart/analysis/features.dart';
5+
import 'dart:async';
6+
7+
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
8+
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
69
import 'package:analyzer/dart/analysis/results.dart';
710
import 'package:analyzer/dart/element/element.dart';
811
import 'package:analyzer/file_system/file_system.dart';
912
import 'package:analyzer/src/context/builder.dart';
10-
import 'package:analyzer/src/context/packages.dart';
11-
import 'package:analyzer/src/dart/analysis/byte_store.dart';
12-
import 'package:analyzer/src/dart/analysis/driver.dart';
13-
import 'package:analyzer/src/dart/analysis/file_state.dart';
14-
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
1513
import 'package:analyzer/src/dart/sdk/sdk.dart';
16-
import 'package:analyzer/src/generated/engine.dart';
1714
import 'package:analyzer/src/generated/java_io.dart';
1815
import 'package:analyzer/src/generated/sdk.dart';
1916
import 'package:analyzer/src/generated/source.dart';
2017
import 'package:analyzer/src/generated/source_io.dart';
21-
import 'package:analyzer/src/source/package_map_resolver.dart';
2218
import 'package:dartdoc/src/dartdoc_options.dart';
2319
import 'package:dartdoc/src/logging.dart';
2420
import 'package:dartdoc/src/model/model.dart' hide Package;
@@ -31,7 +27,6 @@ import 'package:dartdoc/src/special_elements.dart';
3127
import 'package:meta/meta.dart';
3228
// TODO(jcollins-g): do not directly import path, use ResourceProvider instead
3329
import 'package:path/path.dart' as path;
34-
import 'package:pub_semver/pub_semver.dart';
3530

3631
/// Everything you need to instantiate a PackageGraph object for documenting.
3732
abstract class PackageBuilder {
@@ -42,6 +37,7 @@ abstract class PackageBuilder {
4237
/// A package builder that understands pub package format.
4338
class PubPackageBuilder implements PackageBuilder {
4439
final DartdocOptionContext config;
40+
final Set<String> _knownFiles = {};
4541
final PackageMetaProvider packageMetaProvider;
4642
final PackageConfigProvider packageConfigProvider;
4743

@@ -99,8 +95,6 @@ class PubPackageBuilder implements PackageBuilder {
9995

10096
ResourceProvider get resourceProvider => packageMetaProvider.resourceProvider;
10197

102-
/* late final */ Packages packages;
103-
10498
Future<void> _calculatePackageMap() async {
10599
assert(_packageMap == null);
106100
_packageMap = <String, List<Folder>>{};
@@ -110,24 +104,6 @@ class PubPackageBuilder implements PackageBuilder {
110104
if (info == null) return;
111105

112106
var rpc = resourceProvider.pathContext;
113-
// This complicated expression transforms a list of [package_config.Package]
114-
// into [analyzer.Packages]. It's a bit confusing because [info.packages]
115-
// is actually the list of [package_config.Package] objects, rather than
116-
// the [Packages] object we need.
117-
packages = Packages(Map.fromEntries(info.packages.map((p) => MapEntry<
118-
String, Package>(
119-
p.name,
120-
Package(
121-
name: p.name,
122-
rootFolder:
123-
resourceProvider.getFolder(rpc.normalize(rpc.fromUri(p.root))),
124-
languageVersion: p.languageVersion != null
125-
? Version(p.languageVersion.major, p.languageVersion.minor, 0)
126-
: null,
127-
libFolder: resourceProvider.getFolder(
128-
rpc.normalize(rpc.fromUri(p.packageUriRoot)),
129-
))))));
130-
131107
for (var package in info.packages) {
132108
var packagePath = rpc.normalize(rpc.fromUri(package.packageUriRoot));
133109
var resource = resourceProvider.getResource(packagePath);
@@ -139,61 +115,17 @@ class PubPackageBuilder implements PackageBuilder {
139115

140116
/*late final*/ Map<String, List<Folder>> _packageMap;
141117

142-
DartUriResolver _embedderResolver;
118+
AnalysisContextCollection _contextCollection;
143119

144-
DartUriResolver get embedderResolver {
145-
_embedderResolver ??= DartUriResolver(embedderSdk);
146-
return _embedderResolver;
147-
}
148-
149-
SourceFactory get sourceFactory {
150-
final UriResolver packageResolver =
151-
PackageMapUriResolver(resourceProvider, _packageMap);
152-
UriResolver sdkResolver;
153-
if (embedderSdk == null || embedderSdk.urlMappings.isEmpty) {
154-
// The embedder uri resolver has no mappings. Use the default Dart SDK
155-
// uri resolver.
156-
sdkResolver = DartUriResolver(sdk);
157-
} else {
158-
// The embedder uri resolver has mappings, use it instead of the default
159-
// Dart SDK uri resolver.
160-
sdkResolver = embedderResolver;
161-
}
162-
163-
/// [AnalysisDriver] seems to require package resolvers that
164-
/// never resolve to embedded SDK files, and the resolvers list must still
165-
/// contain a DartUriResolver. This hack won't be necessary once analyzer
166-
/// has a clean public API.
167-
var resolvers = [
168-
PackageWithoutSdkResolver(packageResolver, sdkResolver),
169-
sdkResolver,
170-
ResourceUriResolver(resourceProvider),
171-
];
172-
173-
assert(
174-
resolvers.any((UriResolver resolver) => resolver is DartUriResolver));
175-
return SourceFactory(resolvers);
176-
}
177-
178-
AnalysisDriver _driver;
179-
AnalysisDriver get driver {
180-
if (_driver == null) {
181-
var log = PerformanceLog(null);
182-
var scheduler = AnalysisDriverScheduler(log);
183-
var options = AnalysisOptionsImpl()
184-
..hint = false
185-
// TODO(jcollins-g): pass in an ExperimentStatus instead?
186-
..contextFeatures = FeatureSet.fromEnableFlags(config.enableExperiment);
187-
// TODO(jcollins-g): make use of AnalysisContextCollection()
188-
// TODO(jcollins-g): make use of DartProject isApi()
189-
_driver = AnalysisDriver(scheduler, log, resourceProvider,
190-
MemoryByteStore(), FileContentOverlay(), null, sourceFactory, options,
191-
packages: packages);
192-
driver.results.listen((_) => logProgress(''));
193-
driver.exceptions.listen((_) {});
194-
scheduler.start();
195-
}
196-
return _driver;
120+
AnalysisContextCollection get contextCollection {
121+
_contextCollection ??= AnalysisContextCollectionImpl(
122+
includedPaths: [config.inputDir],
123+
// TODO(jcollins-g): should we pass excluded directories here instead of
124+
// handling it ourselves?
125+
resourceProvider: resourceProvider,
126+
sdkPath: config.sdkDir,
127+
);
128+
return _contextCollection;
197129
}
198130

199131
/// Return an Iterable with the sdk files we should parse.
@@ -219,34 +151,20 @@ class PubPackageBuilder implements PackageBuilder {
219151
}
220152
}
221153
var javaFile = JavaFile(filePath).getAbsoluteFile();
222-
Source source = FileBasedSource(javaFile);
223-
224-
// TODO(jcollins-g): remove the manual reversal using embedderSdk when we
225-
// upgrade to analyzer-0.30 (where DartUriResolver implements
226-
// restoreAbsolute)
227-
var uri = embedderSdk?.fromFileUri(source.uri)?.uri;
228-
if (uri != null) {
229-
source = FileBasedSource(javaFile, uri);
230-
} else {
231-
uri = driver.sourceFactory.restoreUri(source);
232-
if (uri != null) {
233-
source = FileBasedSource(javaFile, uri);
234-
}
235-
}
236-
var sourceKind = await driver.getSourceKind(filePath);
154+
filePath = javaFile.getPath();
155+
156+
var analysisContext = contextCollection.contextFor(config.inputDir);
157+
var session = analysisContext.currentSession;
158+
var sourceKind = await session.getSourceKind(filePath);
159+
237160
// Allow dart source files with inappropriate suffixes (#1897). Those
238161
// do not show up as SourceKind.LIBRARY.
239162
if (sourceKind != SourceKind.PART) {
240163
// Loading libraryElements from part files works, but is painfully slow
241164
// and creates many duplicates.
242-
final library =
243-
await driver.currentSession.getResolvedLibrary(source.fullName);
165+
final library = await session.getResolvedLibrary(filePath);
244166
final libraryElement = library.element;
245167
var restoredUri = libraryElement.source.uri.toString();
246-
if (!restoredUri.startsWith('dart:')) {
247-
restoredUri =
248-
driver.sourceFactory.restoreUri(library.element.source).toString();
249-
}
250168
return DartDocResolvedLibrary(library, restoredUri);
251169
}
252170
return null;
@@ -256,6 +174,23 @@ class PubPackageBuilder implements PackageBuilder {
256174
for (var filename in files) packageMetaProvider.fromFilename(filename),
257175
};
258176

177+
void _addKnownFiles(LibraryElement element) {
178+
if (element != null) {
179+
var path = element.source.fullName;
180+
if (_knownFiles.add(path)) {
181+
for (var import in element.imports) {
182+
_addKnownFiles(import.importedLibrary);
183+
}
184+
for (var export in element.exports) {
185+
_addKnownFiles(export.exportedLibrary);
186+
}
187+
for (var part in element.parts) {
188+
_knownFiles.add(part.source.fullName);
189+
}
190+
}
191+
}
192+
}
193+
259194
/// Parses libraries with the analyzer and invokes [libraryAdder] with each
260195
/// result.
261196
///
@@ -268,10 +203,10 @@ class PubPackageBuilder implements PackageBuilder {
268203
[bool Function(LibraryElement) isLibraryIncluded]) async {
269204
isLibraryIncluded ??= (_) => true;
270205
var lastPass = <PackageMeta>{};
271-
Set<PackageMeta> current;
206+
var current = <PackageMeta>{};
272207
var knownParts = <String>{};
273208
do {
274-
lastPass = _packageMetasForFiles(files);
209+
lastPass = current;
275210

276211
// Be careful here not to accidentally stack up multiple
277212
// [DartDocResolvedLibrary]s, as those eat our heap.
@@ -282,17 +217,17 @@ class PubPackageBuilder implements PackageBuilder {
282217
knownParts.add(f);
283218
continue;
284219
}
220+
_addKnownFiles(r.element);
285221
if (!libraries.contains(r.element) && isLibraryIncluded(r.element)) {
286222
logDebug('parsing ${f}...');
287223
libraryAdder(r);
288224
libraries.add(r.element);
289225
}
290226
}
291227

292-
// Be sure to give the analyzer enough time to find all the files.
293-
await driver.discoverAvailableFiles();
294-
files.addAll(driver.knownFiles);
295-
files.addAll(_includeExternalsFrom(driver.knownFiles));
228+
files.addAll(_knownFiles);
229+
files.addAll(_includeExternalsFrom(_knownFiles));
230+
296231
current = _packageMetasForFiles(files.difference(knownParts));
297232
// To get canonicalization correct for non-locally documented packages
298233
// (so we can generate the right hyperlinks), it's vital that we
@@ -504,47 +439,8 @@ class PubPackageBuilder implements PackageBuilder {
504439
}
505440
}
506441

507-
/// This class resolves package URIs, but only if a given SdkResolver doesn't
508-
/// resolve them.
509-
///
510-
/// TODO(jcollins-g): remove this hackery when a clean public API to analyzer
511-
/// exists, and port dartdoc to it.
512-
class PackageWithoutSdkResolver extends UriResolver {
513-
final UriResolver _packageResolver;
514-
final UriResolver _sdkResolver;
515-
516-
PackageWithoutSdkResolver(this._packageResolver, this._sdkResolver);
517-
518-
@override
519-
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
520-
if (_sdkResolver.resolveAbsolute(uri, actualUri) == null) {
521-
return _packageResolver.resolveAbsolute(uri, actualUri);
522-
}
523-
return null;
524-
}
525-
526-
@override
527-
Uri restoreAbsolute(Source source) {
528-
Uri resolved;
529-
try {
530-
resolved = _sdkResolver.restoreAbsolute(source);
531-
} on ArgumentError {
532-
// SDK resolvers really don't like being thrown package paths.
533-
}
534-
if (resolved == null) {
535-
return _packageResolver.restoreAbsolute(source);
536-
}
537-
return null;
538-
}
539-
}
540-
541442
/// Contains the [ResolvedLibraryResult] and any additional information about
542-
/// the library coming from [AnalysisDriver].
543-
///
544-
/// Prefer to populate this class with more information rather than passing
545-
/// [AnalysisDriver] or [AnalysisSession] down to [PackageGraph]. The graph
546-
/// object is reachable by many DartDoc model objects and there's no guarantee
547-
/// that there's a valid [AnalysisDriver] in every environment dartdoc runs.
443+
/// the library.
548444
class DartDocResolvedLibrary {
549445
final ResolvedLibraryResult result;
550446
final String restoredUri;

0 commit comments

Comments
 (0)