diff --git a/examples/misc/lib/effective_dart/docs_good.dart b/examples/misc/lib/effective_dart/docs_good.dart index 5efd309a56..2414d9c57a 100644 --- a/examples/misc/lib/effective_dart/docs_good.dart +++ b/examples/misc/lib/effective_dart/docs_good.dart @@ -1,6 +1,12 @@ -// ignore_for_file: type_annotate_public_apis, unused_element, strict_raw_type +// ignore_for_file: type_annotate_public_apis, unused_element, strict_raw_type, undefined_annotation, experiment_not_enabled, missing_identifier // ignore_for_file: no_leading_underscores_for_local_identifiers, use_function_type_syntax_for_parameters +// #docregion library-doc +/// A really great test library. +@TestOn('browser') +library; +// #enddocregion library-doc + import 'package:examples_util/ellipsis.dart'; void miscDeclAnalyzedButNotTested() { diff --git a/examples/misc/lib/effective_dart/usage_bad.dart b/examples/misc/lib/effective_dart/usage_bad.dart index 028c021482..e33018c1a3 100644 --- a/examples/misc/lib/effective_dart/usage_bad.dart +++ b/examples/misc/lib/effective_dart/usage_bad.dart @@ -7,6 +7,14 @@ // ignore_for_file: prefer_adjacent_string_concatenation, prefer_is_not_empty, prefer_interpolation_to_compose_strings // ignore_for_file: unnecessary_this, always_declare_return_types, no_leading_underscores_for_local_identifiers // ignore_for_file: deprecated_colon_for_default_value +// ignore_for_file: experiment_not_enabled, missing_identifier + +// #docregion library-dir + +library my_library; + +// #enddocregion library-dir + import 'dart:async'; import 'dart:io'; import 'dart:math'; diff --git a/src/_guides/language/effective-dart/documentation.md b/src/_guides/language/effective-dart/documentation.md index e05cf66f95..c50975dc7c 100644 --- a/src/_guides/language/effective-dart/documentation.md +++ b/src/_guides/language/effective-dart/documentation.md @@ -125,9 +125,17 @@ functionality provided within. Consider including: * Links to the most important or most commonly used classes and functions. * Links to external references on the domain the library is concerned with. -You document a library by placing a doc comment right above the `library` -directive at the start of the file. If the library doesn't have a `library` -directive, you can add one just to hang the doc comment off of it. +To document a library, place a doc comment before +the `library` directive and any annotations that might be attached +at the start of the file. + +{:.good} + +{% prettify dart tag=pre+code %} +/// A really great test library. +@TestOn('browser') +library; +{% endprettify %} ### CONSIDER writing doc comments for private APIs. diff --git a/src/_guides/language/effective-dart/style.md b/src/_guides/language/effective-dart/style.md index 0e42b639ff..45c6edb211 100644 --- a/src/_guides/language/effective-dart/style.md +++ b/src/_guides/language/effective-dart/style.md @@ -98,11 +98,11 @@ extension SmartIterable on Iterable { ... } [extensions]: /guides/language/extension-methods -### DO name libraries, packages, directories, and source files using `lowercase_with_underscores`. {#do-name-libraries-and-source-files-using-lowercase_with_underscores} + +### DO name packages, directories, and source files using `lowercase_with_underscores`. {#do-name-packages-and-file-system-entities-using-lowercase-with-underscores} -{% include linter-rule-mention.md rule1="library_names" rule2="file_names" %} +{% include linter-rule-mention.md rule1="file_names" rule2="package_names" %} Some file systems are not case-sensitive, so many projects require filenames to @@ -112,27 +112,20 @@ a valid Dart identifier, which may be helpful if the language later supports symbolic imports. {:.good} - -{% prettify dart tag=pre+code %} -library peg_parser.source_scanner; - -import 'file_system.dart'; -import 'slider_menu.dart'; -{% endprettify %} +```text +my_package +└─ lib + └─ file_system.dart + └─ slider_menu.dart +``` {:.bad} - -{% prettify dart tag=pre+code %} -library pegparser.SourceScanner; - -import 'file-system.dart'; -import 'SliderMenu.dart'; -{% endprettify %} - -{{site.alert.note}} - This guideline specifies *how* to name a library *if you choose to name it*. - It is fine to _omit_ the library directive in a file if you want. -{{site.alert.end}} +```text +mypackage +└─ lib + └─ file-system.dart + └─ SliderMenu.dart +``` ### DO name import prefixes using `lowercase_with_underscores`. @@ -323,6 +316,31 @@ defaultTimeout kDefaultTimeout {% endprettify %} +### DON'T explicitly name libraries + +Appending a name to the `library` directive is technically possible, +but is a legacy feature and discouraged. + +Dart generates a unique tag for each library +based on its path and filename. +Naming libraries overrides this generated URI. +Without the URI, it can be harder for tools to find +the main library file in question. + +{:.bad} + +{% prettify dart tag=pre+code %} + +library my_library; +{% endprettify %} + +{:.good} + +{% prettify dart tag=pre+code %} +/// A really great test library. +@TestOn('browser') +library; +{% endprettify %} ## Ordering diff --git a/src/_guides/language/effective-dart/usage.md b/src/_guides/language/effective-dart/usage.md index 069e633985..d93b63d55e 100644 --- a/src/_guides/language/effective-dart/usage.md +++ b/src/_guides/language/effective-dart/usage.md @@ -19,21 +19,25 @@ but *maintainers* of it sure will. These guidelines help you compose your program out of multiple files in a consistent, maintainable way. To keep these guidelines brief, they use "import" -to cover `import` and `export` directives. The guidelines apply equally to both. +to cover `import` and `export` directives. The guidelines apply equally to both. ### DO use strings in `part of` directives. Many Dart developers avoid using `part` entirely. They find it easier to reason about their code when each library is a single file. If you do choose to use `part` to split part of a library out into another file, Dart requires the other -file to in turn indicate which library it's a part of. For legacy reasons, Dart -allows this `part of` directive to use the *name* of the library it's a part of. -That makes it harder for tools to physically find the main library file, and can -make it ambiguous which library the part is actually part of. +file to in turn indicate which library it's a part of. -The preferred, modern syntax is to use a URI string that points directly to the -library file, just like you use in other directives. If you have some library, -`my_library.dart`, that contains: +Dart allows the `part of` directive to use the *name* of a library. +Naming libraries is a legacy feature that is now [discouraged][]. +Library names can introduce ambiguity +when determining which library a part belongs to. + +[discouraged]: /guides/language/effective-dart/style#dont-explicitly-name-libraries + +The preferred syntax syntax is to use a URI string that points +directly to the library file. +If you have some library, `my_library.dart`, that contains: {% prettify dart tag=pre+code %} @@ -42,7 +46,7 @@ library my_library; part 'some/other/file.dart'; {% endprettify %} -Then the part file should look like: +Then the part file should use the library file's URI string: {:.good} @@ -50,7 +54,7 @@ Then the part file should look like: part of '../../my_library.dart'; {% endprettify %} -And not: +Not the library name: {:.bad} diff --git a/src/_guides/language/language-tour.md b/src/_guides/language/language-tour.md index f49e3f42f8..21f0d52f78 100644 --- a/src/_guides/language/language-tour.md +++ b/src/_guides/language/language-tour.md @@ -4107,7 +4107,7 @@ The `import` and `library` directives can help you create a modular and shareable code base. Libraries not only provide APIs, but are a unit of privacy: identifiers that start with an underscore (`_`) are visible only inside the library. *Every Dart app is a library*, even -if it doesn’t use a `library` directive. +if it doesn’t use a [`library`](#library-directive) directive. Libraries can be distributed using [packages](/guides/packages). @@ -4148,7 +4148,6 @@ import 'package:test/test.dart'; *URLs* (uniform resource locators) are a common kind of URI. {{site.alert.end}} - #### Specifying a library prefix If you import two libraries that have conflicting identifiers, then you @@ -4241,6 +4240,20 @@ Keep in mind the following when you use deferred loading: using deferred as namespace. The `loadLibrary()` function returns a [`Future`](/guides/libraries/library-tour#future). +#### The `library` directive {#library-directive} + +To specify library-level [doc comments][] or [metadata annotations][], +attach them to a `library` declaration at the start of the file. + + +{% prettify dart tag=pre+code %} +/// A really great test library. +@TestOn('browser') +library; +{% endprettify %} + +[doc comments]: /guides/language/effective-dart/documentation#consider-writing-a-library-level-doc-comment +[metadata annotations]: /guides/language/language-tour#metadata ### Implementing libraries @@ -4251,7 +4264,6 @@ for advice on how to implement a library package, including: * How to organize library source code. * How to use the `export` directive. * When to use the `part` directive. -* When to use the `library` directive. * How to use conditional imports and exports to implement a library that supports multiple platforms. diff --git a/src/_guides/libraries/create-library-packages.md b/src/_guides/libraries/create-library-packages.md index 442d24cb43..0e63acafec 100644 --- a/src/_guides/libraries/create-library-packages.md +++ b/src/_guides/libraries/create-library-packages.md @@ -50,14 +50,6 @@ lib directory To make APIs under lib/src public, you can export lib/src files from a file that's directly under lib. -{{site.alert.note}} - When the `library` directive isn't specified, a unique - tag is generated for each library based on its path and filename. - Therefore, we suggest that you omit the `library` directive from - your code unless you plan to - [generate library-level documentation](#documenting-a-library). -{{site.alert.end}} - ## Organizing a library package Library packages are easiest to maintain, extend, and test @@ -272,11 +264,11 @@ void updateBadge() { For an example of generated docs, see the [shelf documentation.]({{site.pub-api}}/shelf/latest) -{{site.alert.note}} - To include any library-level documentation in the generated docs, - you must specify the `library` directive. - See [issue 1082.](https://github.com/dart-lang/dartdoc/issues/1082) -{{site.alert.end}} +To include any *library-level* documentation in the generated docs, +add a `library` directive and attach the comment directly above it. +For the how-and-why of documenting libraries, see +[Effective Dart: Documentation](/guides/language/effective-dart/documentation#consider-writing-a-library-level-doc-comment). + ## Distributing an open source library {#distributing-a-library}