Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.19] Clarify library usage for no-name declarations update #4390

Merged
merged 21 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion examples/misc/lib/effective_dart/docs_good.dart
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
8 changes: 8 additions & 0 deletions examples/misc/lib/effective_dart/usage_bad.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
14 changes: 11 additions & 3 deletions src/_guides/language/effective-dart/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
MaryaBelanger marked this conversation as resolved.
Show resolved Hide resolved

{:.good}
<?code-excerpt "docs_good.dart (library-doc)"?>
{% prettify dart tag=pre+code %}
/// A really great test library.
@TestOn('browser')
library;
{% endprettify %}

### CONSIDER writing doc comments for private APIs.

Expand Down
62 changes: 40 additions & 22 deletions src/_guides/language/effective-dart/style.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ extension SmartIterable<T> on Iterable<T> { ... }

[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}
<a id="do-name-libraries-and-source-files-using-lowercase_with_underscores"></a>
### 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" %}
<!-- source for rules (update these if you update the guideline):
https://github.com/dart-lang/linter/blob/master/lib/src/rules/library_names.dart
https://github.com/dart-lang/linter/blob/master/lib/src/rules/file_names.dart -->

Some file systems are not case-sensitive, so many projects require filenames to
Expand All @@ -112,27 +112,20 @@ a valid Dart identifier, which may be helpful if the language later supports
symbolic imports.

{:.good}
<?code-excerpt "style_lib_good.dart" replace="/foo\///g"?>
{% 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}
<?code-excerpt "style_lib_good.dart" replace="/foo\///g;/file./file-/g;/slider_menu/SliderMenu/g;/source_scanner/SourceScanner/g;/peg_parser/pegparser/g"?>
{% 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`.
Expand Down Expand Up @@ -323,6 +316,31 @@ defaultTimeout
kDefaultTimeout
{% endprettify %}

### DON'T explicitly name libraries

Appending a name to the `library` directive is technically possible,
parlough marked this conversation as resolved.
Show resolved Hide resolved
but is a legacy feature and discouraged.
MaryaBelanger marked this conversation as resolved.
Show resolved Hide resolved

MaryaBelanger marked this conversation as resolved.
Show resolved Hide resolved
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}
<?code-excerpt "usage_bad.dart (library-dir)"?>
{% prettify dart tag=pre+code %}

library my_library;
{% endprettify %}

{:.good}
<?code-excerpt "docs_good.dart (library-doc)"?>
{% prettify dart tag=pre+code %}
/// A really great test library.
@TestOn('browser')
library;
{% endprettify %}

## Ordering

Expand Down
24 changes: 14 additions & 10 deletions src/_guides/language/effective-dart/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

<?code-excerpt "my_library.dart"?>
{% prettify dart tag=pre+code %}
Expand All @@ -42,15 +46,15 @@ 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}
<?code-excerpt "some/other/file.dart"?>
{% prettify dart tag=pre+code %}
part of '../../my_library.dart';
{% endprettify %}

And not:
Not the library name:

{:.bad}
<?code-excerpt "some/other/file_2.dart"?>
Expand Down
18 changes: 15 additions & 3 deletions src/_guides/language/language-tour.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -4241,6 +4240,20 @@ Keep in mind the following when you use deferred loading:
using <code>deferred as <em>namespace</em></code>.
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.

<?code-excerpt "misc/lib/effective_dart/docs_good.dart (library-doc)"?>
{% 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

Expand All @@ -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.

Expand Down
18 changes: 5 additions & 13 deletions src/_guides/libraries/create-library-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}

Expand Down