blob: f78425e7b6b5e8725d6f07989813f8bbb92bf247 [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:dartdoc/src/model/model.dart';
import 'package:meta/meta.dart';
final RegExp _categoryRegExp =
RegExp(r'[ ]*{@(category|subCategory) (.+?)}[ ]*\n?', multiLine: true);
/// Mixin parsing the `@category` directive for ModelElements.
mixin Categorization on DocumentationComment {
@override
String buildDocumentationAddition(String docs) =>
_stripAndSetDartdocCategories(super.buildDocumentationAddition(docs));
/// Parse `{@category ...}` and related information in API comments, stripping
/// out that information from the given comments and returning the stripped
/// version.
String _stripAndSetDartdocCategories(String rawDocs) {
var categorySet = <String>{};
var subCategorySet = <String>{};
_hasCategorization = false;
rawDocs = rawDocs.replaceAllMapped(_categoryRegExp, (match) {
_hasCategorization = true;
switch (match[1]) {
case 'category':
categorySet.add(match[2]!.trim());
case 'subCategory':
subCategorySet.add(match[2]!.trim());
}
return '';
});
_categoryNames = categorySet.toList(growable: false)..sort();
_subCategoryNames = subCategorySet.toList(growable: false)..sort();
return rawDocs;
}
bool get hasSubCategoryNames => subCategoryNames?.isNotEmpty ?? false;
List<String>? _subCategoryNames;
/// Either a set of strings containing all declared subcategories for this symbol,
/// or 'null' if none were declared.
List<String>? get subCategoryNames {
// TODO(jcollins-g): avoid side-effect dependency
if (_subCategoryNames == null) documentationLocal;
return _subCategoryNames;
}
bool get hasCategoryNames => categoryNames?.isNotEmpty ?? false;
List<String>? _categoryNames;
/// Either a set of strings containing all declared categories for this symbol,
/// or 'null' if none were declared.
List<String>? get categoryNames {
// TODO(jcollins-g): avoid side-effect dependency
if (_categoryNames == null) documentationLocal;
return _categoryNames;
}
@visibleForTesting
List<Category> get categories => [
...?categoryNames?.map((n) => package.nameToCategory[n]).nonNulls
]..sort();
Iterable<Category> get displayedCategories {
if (config.showUndocumentedCategories) return categories;
return categories.where((c) => c.isDocumented);
}
bool? _hasCategorization;
/// True if categories, subcategories, or a documentation icon were
/// declared.
late final bool hasCategorization = () {
if (_hasCategorization == null) documentationLocal;
return _hasCategorization ?? false;
}();
}