@@ -1300,7 +1300,7 @@ abstract class Documentable extends Nameable {
1300
1300
abstract class Categorization implements ModelElement {
1301
1301
@override
1302
1302
String _buildDocumentationAddition (String rawDocs) =>
1303
- _stripAndSetDartdocCategories (rawDocs);
1303
+ _stripAndSetDartdocCategories (rawDocs ?? = '' );
1304
1304
1305
1305
/// Parse {@category ...} and related information in API comments, stripping
1306
1306
/// out that information from the given comments and returning the stripped
@@ -2263,7 +2263,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
2263
2263
Set <String > get canonicalFor {
2264
2264
if (_canonicalFor == null ) {
2265
2265
// TODO(jcollins-g): restructure to avoid using side effects.
2266
- documentation ;
2266
+ _buildDocumentationAddition (documentationComment) ;
2267
2267
}
2268
2268
return _canonicalFor;
2269
2269
}
@@ -2273,14 +2273,14 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
2273
2273
///
2274
2274
/// Example:
2275
2275
/// {@canonicalFor libname.ClassName}
2276
- String _setCanonicalFor ( String rawDocs) {
2277
- if (_canonicalFor == null ) {
2278
- _canonicalFor = new Set ( );
2279
- }
2276
+ @override
2277
+ String _buildDocumentationAddition ( String rawDocs ) {
2278
+ rawDocs = super . _buildDocumentationAddition (rawDocs );
2279
+ Set < String > newCanonicalFor = new Set ();
2280
2280
Set <String > notFoundInAllModelElements = new Set ();
2281
2281
final canonicalRegExp = new RegExp (r'{@canonicalFor\s([^}]+)}' );
2282
2282
rawDocs = rawDocs.replaceAllMapped (canonicalRegExp, (Match match) {
2283
- canonicalFor .add (match.group (1 ));
2283
+ newCanonicalFor .add (match.group (1 ));
2284
2284
notFoundInAllModelElements.add (match.group (1 ));
2285
2285
return '' ;
2286
2286
});
@@ -2290,16 +2290,12 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
2290
2290
for (String notFound in notFoundInAllModelElements) {
2291
2291
warn (PackageWarning .ignoredCanonicalFor, message: notFound);
2292
2292
}
2293
- return rawDocs;
2294
- }
2295
-
2296
- String _libraryDocs;
2297
- @override
2298
- String get documentation {
2299
- if (_libraryDocs == null ) {
2300
- _libraryDocs = _setCanonicalFor (super .documentation);
2293
+ // TODO(jcollins-g): warn if a macro/tool _does_ generate an unexpected
2294
+ // canonicalFor?
2295
+ if (_canonicalFor == null ) {
2296
+ _canonicalFor = newCanonicalFor;
2301
2297
}
2302
- return _libraryDocs ;
2298
+ return rawDocs ;
2303
2299
}
2304
2300
2305
2301
/// Libraries are not enclosed by anything.
@@ -3250,13 +3246,14 @@ abstract class ModelElement extends Canonicalization
3250
3246
3251
3247
/// Override this to add more features to the documentation builder in a
3252
3248
/// subclass.
3253
- String _buildDocumentationAddition (String docs) => docs;
3249
+ String _buildDocumentationAddition (String docs) => docs ?? = '' ;
3254
3250
3255
3251
/// Separate from _buildDocumentationLocal for overriding.
3256
3252
String _buildDocumentationBaseSync () {
3257
- assert (_rawDocs == null );
3253
+ assert (_rawDocs == null , 'reentrant calls to _buildDocumentation* not allowed' );
3258
3254
// Do not use the sync method if we need to evaluate tools or templates.
3259
- assert (packageGraph._localDocumentationBuilt);
3255
+ assert (! isCanonical ||
3256
+ ! needsPrecacheRegExp.hasMatch (documentationComment ?? '' ));
3260
3257
if (config.dropTextFrom.contains (element.library.name)) {
3261
3258
_rawDocs = '' ;
3262
3259
} else {
@@ -3273,7 +3270,7 @@ abstract class ModelElement extends Canonicalization
3273
3270
/// Separate from _buildDocumentationLocal for overriding. Can only be
3274
3271
/// used as part of [PackageGraph.setUpPackageGraph] .
3275
3272
Future <String > _buildDocumentationBase () async {
3276
- assert (_rawDocs == null );
3273
+ assert (_rawDocs == null , 'reentrant calls to _buildDocumentation* not allowed' );
3277
3274
// Do not use the sync method if we need to evaluate tools or templates.
3278
3275
if (config.dropTextFrom.contains (element.library.name)) {
3279
3276
_rawDocs = '' ;
@@ -4037,6 +4034,8 @@ abstract class ModelElement extends Canonicalization
4037
4034
'LIBRARY_NAME' : library? .fullyQualifiedName,
4038
4035
'ELEMENT_NAME' : fullyQualifiedNameWithoutLibrary,
4039
4036
'INVOCATION_INDEX' : invocationIndex.toString (),
4037
+ 'PACKAGE_INVOCATION_INDEX' :
4038
+ (package.toolInvocationIndex++ ).toString (),
4040
4039
}..removeWhere ((key, value) => value == null ));
4041
4040
});
4042
4041
} else {
@@ -4688,6 +4687,11 @@ class PackageGraph {
4688
4687
/// Generate a list of futures for any docs that actually require precaching.
4689
4688
Iterable <Future > precacheLocalDocs () sync * {
4690
4689
for (ModelElement m in allModelElements) {
4690
+ // Skip if there is a canonicalModelElement somewhere else we can run this
4691
+ // for. Not the same as allCanonicalModelElements since we need to run
4692
+ // for any ModelElement that might not have a canonical ModelElement,
4693
+ // too.
4694
+ if (m.canonicalModelElement != null && ! m.isCanonical) continue ;
4691
4695
if (m.documentationComment != null &&
4692
4696
needsPrecacheRegExp.hasMatch (m.documentationComment)) {
4693
4697
yield m._precacheLocalDocs ();
@@ -5800,6 +5804,9 @@ class Package extends LibraryContainer
5800
5804
@override
5801
5805
Library get canonicalLibrary => null ;
5802
5806
5807
+ /// Number of times we have invoked a tool for this package.
5808
+ int toolInvocationIndex = 0 ;
5809
+
5803
5810
/// Pieces of the location split by [locationSplitter] (removing package: and
5804
5811
/// slashes).
5805
5812
@override
0 commit comments