Skip to content

Commit e9e2cfd

Browse files
authored
Correct null dereference exception on unusual import URIs (#2429)
* this fixes it, but uses fullname... * Tweak and add test * Fix initialization split across lines
1 parent 6d3c360 commit e9e2cfd

File tree

5 files changed

+31
-18
lines changed

5 files changed

+31
-18
lines changed

lib/src/model/library.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
267267
importedExportedLibraryElements.addAll(element.importedLibraries);
268268
importedExportedLibraryElements.addAll(element.exportedLibraries);
269269
for (var l in importedExportedLibraryElements) {
270-
Library lib = ModelElement.from(l, library, packageGraph);
270+
var lib = packageGraph.findButDoNotCreateLibraryFor(l);
271271
_importedExportedLibraries.add(lib);
272272
_importedExportedLibraries.addAll(lib.importedExportedLibraries);
273273
}

lib/src/model/package_graph.dart

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ class PackageGraph {
4444
/// span packages.
4545
void addLibraryToGraph(DartDocResolvedLibrary resolvedLibrary) {
4646
assert(!allLibrariesAdded);
47-
var element = resolvedLibrary.element;
48-
var packageMeta = packageMetaProvider.fromElement(element, config.sdkDir);
47+
var libraryElement = resolvedLibrary.element;
48+
var packageMeta =
49+
packageMetaProvider.fromElement(libraryElement, config.sdkDir);
4950
var lib = Library.fromLibraryResult(
5051
resolvedLibrary, this, Package.fromPackageMeta(packageMeta, this));
5152
packageMap[packageMeta.name].libraries.add(lib);
52-
allLibraries[element] = lib;
53+
allLibraries[libraryElement.source.fullName] = lib;
5354
}
5455

5556
/// Call during initialization to add a library possibly containing
@@ -203,7 +204,13 @@ class PackageGraph {
203204
}
204205

205206
// All library objects related to this package; a superset of _libraries.
206-
final Map<LibraryElement, Library> allLibraries = {};
207+
// Keyed by [LibraryElement.Source.fullName] to resolve multiple URIs
208+
// referring to the same location to the same [Library]. This isn't how
209+
// Dart works internally, but Dartdoc pretends to avoid documenting or
210+
// duplicating data structures for the same "library" on disk based
211+
// on how it is referenced. We can't use [Source] as a key since because
212+
// of differences in the [TimestampedData] timestamps.
213+
final allLibraries = <String, Library>{};
207214

208215
/// Keep track of warnings
209216
PackageWarningCounter _packageWarningCounter;
@@ -869,32 +876,28 @@ class PackageGraph {
869876
/// set of canonical Libraries).
870877
Library findButDoNotCreateLibraryFor(Element e) {
871878
// This is just a cache to avoid creating lots of libraries over and over.
872-
if (allLibraries.containsKey(e.library)) {
873-
return allLibraries[e.library];
874-
}
875-
return null;
879+
return allLibraries[e.library?.source?.fullName];
876880
}
877881

878882
/// This is used when we might need a Library object that isn't actually
879883
/// a documentation entry point (for elements that have no Library within the
880884
/// set of canonical Libraries).
881885
Library findOrCreateLibraryFor(DartDocResolvedLibrary resolvedLibrary) {
882-
final elementLibrary = resolvedLibrary.library;
883-
// This is just a cache to avoid creating lots of libraries over and over.
884-
if (allLibraries.containsKey(elementLibrary)) {
885-
return allLibraries[elementLibrary];
886-
}
886+
final libraryElement = resolvedLibrary.library;
887887
// can be null if e is for dynamic
888-
if (elementLibrary == null) {
888+
if (libraryElement == null) {
889889
return null;
890890
}
891-
var foundLibrary = Library.fromLibraryResult(
891+
var foundLibrary = findButDoNotCreateLibraryFor(libraryElement);
892+
if (foundLibrary != null) return foundLibrary;
893+
894+
foundLibrary = Library.fromLibraryResult(
892895
resolvedLibrary,
893896
this,
894897
Package.fromPackageMeta(
895-
packageMetaProvider.fromElement(elementLibrary, config.sdkDir),
898+
packageMetaProvider.fromElement(libraryElement, config.sdkDir),
896899
packageGraph));
897-
allLibraries[elementLibrary] = foundLibrary;
900+
allLibraries[libraryElement.source.fullName] = foundLibrary;
898901
return foundLibrary;
899902
}
900903

test/end2end/model_test.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,13 @@ void main() {
604604
isTrue);
605605
});
606606

607+
test('can import other libraries with unusual URIs', () {
608+
expect(
609+
fakeLibrary.importedExportedLibraries
610+
.where((l) => l.name == 'import_unusual'),
611+
isNotEmpty);
612+
});
613+
607614
test('@canonicalFor directive works', () {
608615
expect(SomeOtherClass.canonicalLibrary, reexportOneLib);
609616
expect(SomeClass.canonicalLibrary, reexportTwoLib);

testing/test_package/lib/fake.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import 'dart:json' as invalidPrefix;
5454
import 'package:meta/meta.dart' show Required;
5555
import 'csspub.dart' as css;
5656
import 'csspub.dart' as renamedLib2;
57+
import 'package:test_package/src//import_unusual.dart';
5758
import 'example.dart';
5859
import 'mylibpub.dart' as renamedLib;
5960
import 'mylibpub.dart' as renamedLib2;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// This library exists only to be imported with an unusual URI.
2+
library import_unusual;

0 commit comments

Comments
 (0)