dart-lang / dartdoc

API documentation tool for Dart.
https://pub.dev/packages/dartdoc
BSD 3-Clause "New" or "Revised" License
473 stars 119 forks source link

Documentation is not properly contained in library boundaries #2142

Closed JonHodgson closed 4 years ago

JonHodgson commented 4 years ago

If we look at google_maps_webservice for an example.

In the source we have directions.dart

library google_maps_webservice.directions;

export './src/core.dart';
export './src/directions.dart';

And we have distance.dart

library google_maps_webservice.distance;

export './src/core.dart';
export './src/distance.dart';

Now as you can see, both of those export core.dart, which starts

library google_maps_webservice.core;

class Location {

Now to me, it seems that dartdoc should generate documentation for three libraries from that source code. google_maps_webservice.directions google_maps_webservice.distance google_maps_webservice.core

With the Location class appearing only as a member of the core library

But instead, only the first two appear as libraries in the documentation, and the Location class is replicated in the directions and distance classes Package Documentation

Is this the intended behaviour, and is there a way to make dartdoc produce what I would have expected given that source code?

jcollins-g commented 4 years ago

src/core.dart is not part of the public interface (approximately, libraries under lib but not under lib/src), so Dartdoc is only documenting the core library via others that export it.

To begin correcting this problem, I suggest moving core.dart to lib, or creating core.dart in lib and having it reexport the library under src. Then the other libraries become:

library google_maps_webservice.directions;

export 'core.dart';
export 'src/directions.dart';

and:

library google_maps_webservice.distance;

export 'core.dart';
export 'src/distance.dart';

Dartdoc is smart enough to follow the reexport tree and note that all reexports come from one public source, and redirect canonicalization to be from that one source. In the event the situation is ambiguous, dartdoc will emit a warning and pick one according to a heuristic, which can be overridden via the dartdoc directive @canonicalFor. See https://github.com/dart-lang/dartdoc/blob/285b4df2fd3781461d7f3492edf3bbd649995f55/lib/src/warnings.dart#L122.

Note that Dartdoc surfaces the Location class anywhere it is reexported; if you don't want it to do that, do not reexport it in so many places. It will not (unless there is a bug) actually duplicate it. If you notice in the example you gave Location is actually canonicalized to be under google_maps_webservice.timezone and all links in other libraries link to the version there (I checked a couple and this seems to be working correctly). This is a situation that dartdoc is complaining about as I mentioned above, and you can see those complaints here: https://pub.dev/documentation/google_maps_webservice/latest/log.txt

e.g.:

  warning: ambiguous reexport of google_maps_webservice.core.Location, canonicalization candidates: (google_maps_webservice.directions, google_maps_webservice.distance, google_maps_webservice.geocoding, ..., google_maps_webservice.places, google_maps_webservice.timezone) -> google_maps_webservice.timezone (confidence 0.000)
    from google_maps_webservice.core.Location: (file:///tmp/pub-dartlang-dartdocKQWWIK/pkg/lib/src/core.dart:3:7)
        google_maps_webservice.directions: 0.2200 - name is long (+0.02000), element location shares parts with name (+0.2000)
        google_maps_webservice.distance: 0.2200 - name is long (+0.02000), element location shares parts with name (+0.2000)
        google_maps_webservice.geocoding: 0.2200 - name is long (+0.02000), element location shares parts with name (+0.2000)
        google_maps_webservice.geolocation: 0.2200 - name is long (+0.02000), element location shares parts with name (+0.2000)
        google_maps_webservice.places: 0.2200 - name is long (+0.02000), element location shares parts with name (+0.2000)
        google_maps_webservice.timezone: 0.2200 - name is long (+0.02000), element location shares parts with name (+0.2000)

This is a situation that you can solve by restructuring your library as above, and if dartdoc complains and chooses wrongly, you can file a bug and/or use @canonicalFor to pick a different candidate.

Hope this helps!

JonHodgson commented 4 years ago

Thanks, google_maps_webservice isn't my project, but I used it since it gave a good example of what I'm running into with mine. I'll have a play using your instructions as a guideline and see how it goes.