diff --git a/README.md b/README.md index 1dd28db41e..b49dee1fd7 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,6 @@ dartdoc: markdown: doc/Second.md name: Great categoryOrder: ["First Category", "Second Category"] - examplePathPrefix: 'subdir/with/examples' includeExternal: ['bin/unusually_located_library.dart'] nodoc: ['lib/sekret/*.dart'] linkTo: @@ -150,8 +149,6 @@ Unrecognized options will be ignored. Supported options: defined in dartdoc_options.yaml, those declared categories in the source code will be invisible. * **categoryOrder**: Specify the order of topics for display in the sidebar and the package page. - * **examplePathPrefix**: Specify the location of the example directory for resolving `@example` - directives. * **exclude**: Specify a list of library names to avoid generating docs for, overriding any specified in include. All libraries listed must be local to this package, unlike the command line `--exclude`. See also `nodoc`. diff --git a/doc/directives.md b/doc/directives.md index 59c31f9f20..eddf6ed616 100644 --- a/doc/directives.md +++ b/doc/directives.md @@ -28,27 +28,6 @@ own documentation page, listing all of the categorized elements. TODO(srawlins): Document. -## `{@example}` - Examples (deprecated) - -Examples from the file system can be inlined by using the `{@example}` -directive. The file path, the region, and the example language can all be -specified with the following syntax: - -```none -/// {@example PATH [region=NAME] [lang=NAME]} -``` - -All example file names must have the extension, `.md`, and this extension must -not be specified in the example `PATH`. `PATH` must be specified as a relative -path from the root of the project for which documentation is being generated. -Given `dir/file.dart` as `PATH`, an example will be extracted from -`dir/file.dart.md`, relative to the project root directory. - -During doc generation, dartdoc will replace the `{@example}` directive with the -contents of the example file, verbatim. - -TODO(srawlins): Document region, lang, `--example-path-prefix`. - ## `{@inject-html}` - Injected HTML HTML can be rendered unmodified by including it between `{@inject-html}` and diff --git a/lib/src/dartdoc_options.dart b/lib/src/dartdoc_options.dart index b73d2e3ca2..dd7ad6c0ab 100644 --- a/lib/src/dartdoc_options.dart +++ b/lib/src/dartdoc_options.dart @@ -1293,10 +1293,6 @@ class DartdocOptionContext extends DartdocOptionContextBase CategoryConfiguration get categories => optionSet['categories'].valueAt(context); - // TODO(srawlins): Remove when we remove support for `{@example}`. - String? get examplePathPrefix => - optionSet['examplePathPrefix'].valueAt(context); - // TODO(srawlins): This memoization saved a lot of time in unit testing, but // is the first value in this class to be memoized. Memoize others? late final Set exclude = @@ -1554,12 +1550,6 @@ List createDartdocOptions( convertYamlToType: CategoryConfiguration.fromYamlMap, help: 'A list of all categories, their display names, and markdown ' 'documentation in the order they are to be displayed.'), - // TODO(srawlins): Remove when we remove support for `{@example}`. - DartdocOptionArgFile('examplePathPrefix', null, resourceProvider, - optionIs: OptionKind.dir, - help: '(deprecated) Prefix for @example paths; defaults to the project ' - 'root.', - mustExist: true), DartdocOptionArgFile>('exclude', [], resourceProvider, help: 'Names of libraries to exclude from documentation.', splitCommas: true), diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart index b37c9e0113..8ab27dc425 100644 --- a/lib/src/generator/templates.runtime_renderers.dart +++ b/lib/src/generator/templates.runtime_renderers.dart @@ -16097,7 +16097,6 @@ const _invisibleGetters = { 'categories', 'categoryOrder', 'context', - 'examplePathPrefix', 'exclude', 'excludeFooterVersion', 'flutterRoot', diff --git a/lib/src/model/documentation_comment.dart b/lib/src/model/documentation_comment.dart index e023d0eff7..154ba60218 100644 --- a/lib/src/model/documentation_comment.dart +++ b/lib/src/model/documentation_comment.dart @@ -24,8 +24,6 @@ final _htmlPattern = final _basicToolPattern = RegExp(r'[ ]*{@tool\s+([^\s}][^}]*)}\n?([^]+?)\n?{@end-tool}[ ]*\n?'); -final _examplePattern = RegExp(r'{@example\s+([^\s}][^}]*)}'); - final _macroRegExp = RegExp(r'{@macro\s+([^\s}][^}]*)}'); final _htmlInjectRegExp = RegExp(r'([a-f0-9]+)'); @@ -97,7 +95,6 @@ mixin DocumentationComment String _processCommentWithoutTools(String documentationComment) { var docs = stripComments(documentationComment); if (docs.contains('{@')) { - docs = _injectExamples(docs); docs = _injectYouTube(docs); docs = _injectAnimations(docs); // TODO(srawlins): Processing templates here causes #2281. But leaving @@ -126,7 +123,6 @@ mixin DocumentationComment return docs; } _checkForUnknownDirectives(docs); - docs = _injectExamples(docs); docs = _injectYouTube(docs); docs = _injectAnimations(docs); docs = _stripMacroTemplatesAndAddToIndex(docs); @@ -147,7 +143,6 @@ mixin DocumentationComment 'end-inject-html', 'end-tool', 'endtemplate', - 'example', 'macro', 'inject-html', 'template', @@ -284,105 +279,6 @@ mixin DocumentationComment .cast(); } - /// Replace {@example ...} in API comments with the content of named file. - /// - /// Syntax: - /// - /// {@example PATH [region=NAME] [lang=NAME]} - /// - /// If PATH is `dir/file.ext` and region is `r` then we'll look for the file - /// named `dir/file-r.ext.md`, relative to the project root directory of the - /// project for which the docs are being generated. - /// - /// Examples: (escaped in this comment to show literal values in dartdoc's - /// dartdoc) - /// - /// {@example examples/angular/quickstart/web/main.dart} - /// {@example abc/def/xyz_component.dart region=template lang=html} - /// - String _injectExamples(String rawdocs) { - final dirPath = package.packageMeta.dir.path; - return rawdocs.replaceAllMapped(_examplePattern, (match) { - var args = _getExampleArgs(match[1]!); - if (args == null) { - // Already warned about an invalid parameter if this happens. - return ''; - } - warn( - PackageWarning.deprecated, - message: - "The '@example' directive is deprecated, and will soon no longer " - 'be supported.', - ); - var lang = args['lang'] ?? - pathContext.extension(args['src']!).replaceFirst('.', ''); - - var replacement = match[0]!; // default to fully matched string. - - var fragmentFile = packageGraph.resourceProvider.getFile( - pathContext.canonicalize(pathContext.join(dirPath, args['file']))); - - if (fragmentFile.exists) { - replacement = fragmentFile.readAsStringSync(); - if (lang.isNotEmpty) { - replacement = replacement.replaceFirst('```', '```$lang'); - } - } else { - var filePath = element.source!.fullName.substring(dirPath.length + 1); - - // TODO(srawlins): If a file exists at the location without the - // appended 'md' extension, note this. - warn(PackageWarning.missingExampleFile, - message: '${fragmentFile.path}; path listed at $filePath'); - } - return replacement; - }); - } - - /// An argument parser used in [_getExampleArgs] to parse an `{@example}` - /// directive. - static final ArgParser _exampleArgParser = ArgParser() - ..addOption('lang') - ..addOption('region'); - - /// Helper for [_injectExamples] used to process `@example` arguments. - /// - /// Returns a map of arguments. The first unnamed argument will have key - /// 'src'. The computed file path, constructed from 'src' and 'region' will - /// have key 'file'. - Map? _getExampleArgs(String argsAsString) { - var results = _parseArgs(argsAsString, _exampleArgParser, 'example'); - if (results == null) { - return null; - } - - // Extract PATH and fix the path separators. - var src = results.rest.isEmpty - ? '' - : results.rest.first.replaceAll('/', pathContext.separator); - var args = { - 'src': src, - 'lang': results['lang'], - 'region': results['region'] ?? '', - }; - - // Compute 'file' from region and src. - final fragExtension = '.md'; - var file = src + fragExtension; - var region = args['region'] ?? ''; - if (region.isNotEmpty) { - var dir = pathContext.dirname(src); - var basename = pathContext.basenameWithoutExtension(src); - var ext = pathContext.extension(src); - file = pathContext.join(dir, '$basename-$region$ext$fragExtension'); - } - var examplePathPrefix = config.examplePathPrefix; - args['file'] = examplePathPrefix == null - ? file - : pathContext.join(examplePathPrefix, file); - return args; - } - /// Matches all youtube directives (even some invalid ones). This is so /// we can give good error messages if the directive is malformed, instead of /// just silently emitting it as-is. diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart index e7cc4d0391..b242c23107 100644 --- a/lib/src/model/package_graph.dart +++ b/lib/src/model/package_graph.dart @@ -459,7 +459,6 @@ class PackageGraph with CommentReferable, Nameable { PackageWarning.invalidParameter || PackageWarning.toolError || PackageWarning.deprecated || - PackageWarning.missingExampleFile || PackageWarning.missingCodeBlockLanguage => kind.messageFor([message]) }; diff --git a/lib/src/warnings.dart b/lib/src/warnings.dart index 1ca83431dc..1aac79d27d 100644 --- a/lib/src/warnings.dart +++ b/lib/src/warnings.dart @@ -279,13 +279,6 @@ enum PackageWarning implements Comparable { 'deprecated dartdoc usage: {0}', shortHelp: 'A dartdoc directive has a deprecated format.', ), - missingExampleFile( - 'missing-example-file', - 'example file not found: {0}', - shortHelp: - "A file which is indicated by an '{@example}' directive could not be " - 'found', - ), missingCodeBlockLanguage( 'missing-code-block-language', 'missing code block language: {0}', diff --git a/test/documentation_comment_test.dart b/test/documentation_comment_test.dart index 437ddd6b54..8088697899 100644 --- a/test/documentation_comment_test.dart +++ b/test/documentation_comment_test.dart @@ -404,198 +404,6 @@ End text.''')); expect(doc, equals('{@macro abc}')); } - void test_processesExampleDirectiveWithFile() async { - projectRoot.getChildAssumingFile('abc.md').writeAsStringSync(''' -```plaintext -Code snippet -``` -'''); - var doc = await libraryModel.processComment(''' -/// Text. -/// -/// {@example abc} -/// -/// End text. -'''); - - expect( - libraryModel, - hasDeprecatedWarning( - "The '@example' directive is deprecated, and will soon no longer be " - 'supported.', - ), - ); - expect(doc, equals(''' -Text. - -```plaintext -Code snippet -``` - - -End text.''')); - } - - void test_processesExampleDirectiveWithRegion() async { - projectRoot - .getChildAssumingFile('abc-r.md') - .writeAsStringSync('Markdown text.'); - var doc = await libraryModel.processComment(''' -/// Text. -/// -/// {@example region=r abc} -'''); - - expect( - libraryModel, - hasDeprecatedWarning( - "The '@example' directive is deprecated, and will soon no longer be " - 'supported.', - ), - ); - expect(doc, equals(''' -Text. - -Markdown text.''')); - } - - void test_addsLanguageToProcessedExampleWithExtensionAndNoLang() async { - projectRoot.getChildAssumingFile('abc.html.md').writeAsStringSync(''' -``` -Code snippet -``` -'''); - var doc = await libraryModel.processComment(''' -/// Text. -/// -/// {@example abc.html} -/// -/// End text. -'''); - - expect( - libraryModel, - hasDeprecatedWarning( - "The '@example' directive is deprecated, and will soon no longer be " - 'supported.', - ), - ); - expect(doc, equals(''' -Text. - -```html -Code snippet -``` - - -End text.''')); - } - - void test_addsLanguageToProcessedExampleWithLangAndAnExtension() async { - projectRoot.getChildAssumingFile('abc.html.md').writeAsStringSync(''' -``` -Code snippet -``` -'''); - var doc = await libraryModel.processComment(''' -/// Text. -/// -/// {@example abc.html lang=html} -'''); - - expect( - libraryModel, - hasDeprecatedWarning( - "The '@example' directive is deprecated, and will soon no longer be " - 'supported.', - ), - ); - expect(doc, equals(''' -Text. - -```html -Code snippet -``` -''')); - } - - void - test_addsLanguageToProcessedExampleDirectiveWithLangAndNoExtension() async { - projectRoot.getChildAssumingFile('abc.md').writeAsStringSync(''' -``` -Code snippet -``` -'''); - var doc = await libraryModel.processComment(''' -/// Text. -/// -/// {@example abc lang=html} -'''); - - expect( - libraryModel, - hasDeprecatedWarning( - "The '@example' directive is deprecated, and will soon no longer be " - 'supported.', - ), - ); - expect(doc, equals(''' -Text. - -```html -Code snippet -``` -''')); - } - - void test_processesExampleDirectiveWithFileNotFound() async { - var doc = await libraryModel.processComment(''' -/// {@example abc} -'''); - - var abcPath = resourceProvider.pathContext.canonicalize( - resourceProvider.pathContext.join(projectRoot.path, 'abc.md')); - var libPathInWarning = resourceProvider.pathContext.join('lib', 'a.dart'); - expect( - libraryModel, - hasDeprecatedWarning( - "The '@example' directive is deprecated, and will soon no longer be " - 'supported.', - ), - ); - expect(libraryModel, - hasMissingExampleWarning('$abcPath; path listed at $libPathInWarning')); - // When the example path is invalid, the directive should be left in-place. - expect(doc, equals('{@example abc}')); - } - - void test_processesExampleDirectiveWithDirectoriesNotFound() async { - var doc = await libraryModel.processComment(''' -/// {@example abc/def/ghi} -'''); - var abcPath = resourceProvider.pathContext.canonicalize(resourceProvider - .pathContext - .join(projectRoot.path, 'abc', 'def', 'ghi.md')); - var libPathInWarning = resourceProvider.pathContext.join('lib', 'a.dart'); - expect(libraryModel, - hasMissingExampleWarning('$abcPath; path listed at $libPathInWarning')); - // When the example path is invalid, the directive should be left in-place. - expect(doc, equals('{@example abc/def/ghi}')); - } - - void test_processesExampleDirectiveWithRegionNotFound() async { - var doc = await libraryModel.processComment(''' -/// {@example region=r abc} -'''); - var abcPath = resourceProvider.pathContext.canonicalize( - resourceProvider.pathContext.join(projectRoot.path, 'abc-r.md')); - var libPathInWarning = resourceProvider.pathContext.join('lib', 'a.dart'); - expect(libraryModel, - hasMissingExampleWarning('$abcPath; path listed at $libPathInWarning')); - // When the example path is invalid, the directive should be left in-place. - expect(doc, equals('{@example region=r abc}')); - } - void test_leavesInjectHtmlDirectiveUnprocessedWhenDisabled() async { var doc = await libraryModel.processComment(''' /// Text. @@ -869,9 +677,6 @@ Text. Matcher hasInvalidParameterWarning(String message) => _HasWarning(PackageWarning.invalidParameter, message); - Matcher hasMissingExampleWarning(String message) => - _HasWarning(PackageWarning.missingExampleFile, message); - // TODO(srawlins): More unit tests: @tool. } diff --git a/test/options_test.dart b/test/options_test.dart index 04791f07f6..7d553eed69 100644 --- a/test/options_test.dart +++ b/test/options_test.dart @@ -151,43 +151,6 @@ dartdoc: expect(version.hasMatch(match.group(0)!), false, reason: indexContent); } - void test_examplePathPrefixOption_findsExamplesInACustomPath() async { - await createPackage( - dartdocOptions: ''' -dartdoc: - examplePathPrefix: 'package_examples' -''', - libFiles: [ - d.file('lib.dart', ''' -/// An example in a non-default location: -/// -/// {@example foo.dart} -class Foo {} -'''), - ], - files: [ - d.dir('package_examples', [ - d.file('foo.dart.md', ''' -``` -An example in an unusual dir. -``` -'''), - ]), - ], - ); - final packageGraph = await bootBasicPackage( - packagePath, - packageMetaProvider, - packageConfigProvider, - ); - final classFoo = packageGraph.allLocalModelElements - .where((e) => e.isCanonical) - .whereType() - .firstWhere((c) => c.name == 'Foo'); - expect(classFoo.documentationAsHtml, - contains('An example in an unusual dir.')); - } - void test_includeOption_canBeSpecifiedInOptionsFile() async { await createPackage( dartdocOptions: '''