Skip to content

Commit f24562a

Browse files
authored
Correct a regression for a package with a specified set of included libraries (#3825)
Correct a regression for a package with a specified set of included libraries In 12d271a we change what libraries can count as a 'canonical library', such that when a set of libraries is specified with the 'include' option, any library not in the 'include' list is not canonical. This breaks a few things. The fix is to add all libraries to the `_allLibraries` field, not taking the 'include' list into consideration. Then when we decide what libraries are considered to be part of a package, we filter down to 'included' libraries.
1 parent 1e6d551 commit f24562a

File tree

8 files changed

+86
-36
lines changed

8 files changed

+86
-36
lines changed

lib/src/model/category.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Category
2121
TopLevelContainer,
2222
Indexable
2323
implements Documentable {
24-
/// All libraries in [libraries] must come from [_package].
24+
/// All libraries in [libraries] must come from [package].
2525
@override
2626
final Package package;
2727

lib/src/model/library.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import 'package:analyzer/dart/element/element.dart';
66
import 'package:analyzer/dart/element/scope.dart';
77
import 'package:analyzer/source/line_info.dart';
8-
// ignore: implementation_imports
9-
import 'package:analyzer/src/generated/sdk.dart' show SdkLibrary;
108
import 'package:dartdoc/src/model/comment_referable.dart';
119
import 'package:dartdoc/src/model/model.dart';
1210
import 'package:dartdoc/src/package_meta.dart' show PackageMeta;
@@ -107,13 +105,17 @@ class Library extends ModelElement
107105
CompilationUnitElement get compilationUnitElement =>
108106
element.definingCompilationUnit;
109107

110-
SdkLibrary? get _sdkLib =>
111-
packageGraph.sdkLibrarySources[element.librarySource];
112-
113108
@override
109+
110+
/// Whether this library is considered "public."
111+
///
112+
/// A library is considered public if it:
113+
/// * is an SDK library and it is documented and it is not internal, or
114+
/// * is found in a package's top-level 'lib' directory, and
115+
/// not found in it's 'lib/src' directory, and it is not excluded.
114116
bool get isPublic {
115117
if (!super.isPublic) return false;
116-
final sdkLib = _sdkLib;
118+
final sdkLib = packageGraph.sdkLibrarySources[element.librarySource];
117119
if (sdkLib != null && (sdkLib.isInternal || !sdkLib.isDocumented)) {
118120
return false;
119121
}

lib/src/model/nameable.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ mixin Nameable {
3030
///
3131
/// A "package-public" element satisfies the following requirements:
3232
/// * is not documented with the `@nodoc` directive,
33-
/// * for a library, is found in a package's top-level 'lib' directory, and
34-
/// not found in it's 'lib/src' directory,
33+
/// * for a library, adheres to the documentation for [Library.isPublic],
3534
/// * for a library member, is in a _public_ library's exported namespace, and
3635
/// is not privately named, nor an unnamed extension,
3736
/// * for a container (class, enum, extension, extension type, mixin) member,

lib/src/model/package_builder.dart

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,8 @@ class PubPackageBuilder implements PackageBuilder {
286286
if (processedLibraries.contains(resolvedLibrary.element)) {
287287
continue;
288288
}
289-
if (addingSpecials || _shouldIncludeLibrary(resolvedLibrary.element)) {
290-
addLibrary(resolvedLibrary);
291-
processedLibraries.add(resolvedLibrary.element);
292-
}
289+
addLibrary(resolvedLibrary);
290+
processedLibraries.add(resolvedLibrary.element);
293291
}
294292
files.addAll(newFiles);
295293
if (!addingSpecials) {
@@ -329,10 +327,6 @@ class PubPackageBuilder implements PackageBuilder {
329327
}
330328
}
331329

332-
/// Whether [libraryElement] should be included in the libraries-to-document.
333-
bool _shouldIncludeLibrary(LibraryElement libraryElement) =>
334-
_config.include.isEmpty || _config.include.contains(libraryElement.name);
335-
336330
/// Returns all top level library files in the 'lib/' directory of the given
337331
/// package root directory.
338332
///

lib/src/model/package_graph.dart

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,17 @@ class PackageGraph with CommentReferable, Nameable {
107107
'that `$dartOrFlutter analyze` completes without errors.');
108108
}
109109
var package = Package.fromPackageMeta(packageMeta, this);
110-
var lib = Library.fromLibraryResult(resolvedLibrary, this, package);
111-
package.libraries.add(lib);
112-
_allLibraries[libraryElement.source.fullName] = lib;
110+
var library = Library.fromLibraryResult(resolvedLibrary, this, package);
111+
if (_shouldIncludeLibrary(libraryElement)) {
112+
package.libraries.add(library);
113+
}
114+
_allLibraries[libraryElement.source.fullName] = library;
113115
}
114116

117+
/// Whether [libraryElement] should be included in the libraries-to-document.
118+
bool _shouldIncludeLibrary(LibraryElement libraryElement) =>
119+
config.include.isEmpty || config.include.contains(libraryElement.name);
120+
115121
/// Adds [resolvedLibrary] as a special library to the package graph, which
116122
/// adds the library to [_allLibraries], but does not add it to any [Package]'s
117123
/// list of libraries.
@@ -346,10 +352,10 @@ class PackageGraph with CommentReferable, Nameable {
346352
/// [libraries].
347353
///
348354
/// Keyed by `LibraryElement.source.fullName` to resolve different URIs
349-
/// referring to the same location, to the same [Library]. This isn't how Dart
350-
/// works internally, but Dartdoc pretends to avoid documenting or duplicating
351-
/// data structures for the same "library" on disk based on how it is
352-
/// referenced. We can't use [Source] as a key due to differences in the
355+
/// referring to the same location, and hence to the same [Library]. This
356+
/// isn't how Dart works internally, but Dartdoc pretends to avoid documenting
357+
/// or duplicating data structures for the same library on disk based on how
358+
/// it is referenced. We can't use [Source] as a key due to differences in the
353359
/// [TimestampedData] timestamps.
354360
///
355361
/// This mapping must be complete before [initializePackageGraph] is called.
@@ -556,14 +562,19 @@ class PackageGraph with CommentReferable, Nameable {
556562
}
557563
}
558564

559-
int _lastSizeOfAllLibraries = 0;
565+
int _previousSizeOfAllLibraries = 0;
560566

561567
/// A mapping from a [LibraryElement] to all of the [Library]s that export it,
562568
/// which is created if it is not yet populated.
563569
Map<LibraryElement, Set<Library>> get libraryExports {
564-
// Table must be reset if we're still in the middle of adding libraries.
565-
if (_allLibraries.keys.length != _lastSizeOfAllLibraries) {
566-
_lastSizeOfAllLibraries = _allLibraries.keys.length;
570+
// The map must be reset if we're still in the middle of adding libraries
571+
// (though this shouldn't happen).
572+
if (_allLibraries.keys.length != _previousSizeOfAllLibraries) {
573+
assert(
574+
_previousSizeOfAllLibraries == 0,
575+
'Re-entered `libraryExports` while building all libraries',
576+
);
577+
_previousSizeOfAllLibraries = _allLibraries.keys.length;
567578
_libraryExports = {};
568579
for (var library in publicLibraries) {
569580
_tagExportsFor(library, library.element);

test/element_type_test.dart

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,9 @@ void main() async {
2828
late FakePackageConfigProvider packageConfigProvider;
2929
late String packagePath;
3030

31-
Future<void> setUpPackage(
32-
String name, {
33-
String? pubspec,
34-
String? analysisOptions,
35-
}) async {
31+
Future<void> setUpPackage(String name) async {
3632
packagePath = await d.createPackage(
3733
name,
38-
pubspec: pubspec,
39-
analysisOptions: analysisOptions,
4034
resourceProvider: resourceProvider,
4135
);
4236

test/options_test.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@ class OptionsTest extends DartdocTestBase {
2828
static const packageName = 'test_package';
2929

3030
Future<void> createPackage({
31+
String? pubspec,
3132
String? dartdocOptions,
3233
List<d.Descriptor> libFiles = const [],
3334
List<d.Descriptor> files = const [],
3435
}) async {
3536
packagePath = await d.createPackage(
3637
packageName,
38+
pubspec: pubspec,
3739
dartdocOptions: dartdocOptions,
3840
libFiles: libFiles,
3941
files: files,
@@ -181,6 +183,51 @@ class Baz {}
181183
orderedEquals(['library_1', 'library_2']));
182184
}
183185

186+
void test_includeOption_referringToNotIncluded() async {
187+
await createPackage(
188+
pubspec: '''
189+
name: options
190+
version: 0.0.1
191+
environment:
192+
sdk: '>=3.4.0 <4.0.0'
193+
dependencies:
194+
http:
195+
path: vendor/http
196+
''',
197+
dartdocOptions: '''
198+
dartdoc:
199+
include: ["library_1"]
200+
''',
201+
libFiles: [
202+
d.file('library_1.dart', '''
203+
library library_1;
204+
import 'package:http/http.dart' as http;
205+
class Foo {
206+
http.Client? client;
207+
}
208+
'''),
209+
],
210+
files: [
211+
d.dir('vendor', [
212+
d.dir('http', [
213+
d.dir('lib', [d.file('http.dart', 'class Client {}')])
214+
])
215+
])
216+
],
217+
);
218+
final packageGraph = await bootBasicPackage(
219+
packagePath,
220+
packageMetaProvider,
221+
packageConfigProvider,
222+
);
223+
expect(packageGraph.localPublicLibraries.map((l) => l.name),
224+
orderedEquals(['library_1']));
225+
final foo =
226+
packageGraph.localPackages.first.libraries.first.classes.named('Foo');
227+
// The name is not linked, but also does not error.
228+
expect(foo.allFields.first.modelType.linkedName, 'Client?');
229+
}
230+
184231
void test_includeCommandLineOption_overridesOptionsFileOption() async {
185232
await createPackage(
186233
dartdocOptions: '''

test/src/test_descriptor_utils.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ Future<String> createPackage(
4848
final dependencies = parsedYaml['dependencies'] as Map;
4949
for (var dep in dependencies.keys) {
5050
// This only accepts 'path' deps.
51-
final depConfig = dependencies[dep] as Map;
51+
final depConfig = dependencies[dep];
52+
if (depConfig is! Map) {
53+
throw StateError('dep in pubspec must be a Map, but is: "$depConfig"');
54+
}
5255
final pathDep = depConfig['path'];
5356

5457
packagesInfo.writeln(''',{

0 commit comments

Comments
 (0)