# Dart API Readability Rubric

[TOC]

## Overview

This document describes heuristics and rules for writing Dart libraries that are
published in the Fuchsia SDK.

Unless otherwise specified, Fuchsia library authors should adhere to all the
heuristics and rules recommended by the Dart team itself under [Effective
Dart](https://www.dartlang.org/guides/language/effective-dart). Author’s should
familiarize themselves with all sections,
[Style](https://www.dartlang.org/guides/language/effective-dart/style),
[Documentation](https://www.dartlang.org/guides/language/effective-dart/documentation),
[Usage](https://www.dartlang.org/guides/language/effective-dart/usage) and
[Design](https://www.dartlang.org/guides/language/effective-dart/design) prior
to reading this rubric.

### Terminology

There are some terms of art that Dart uses that conflict with Fuchsia’s
terminology.

- [Fuchsia
  package](/src/sys/pkg/bin/pm/README.md#structure-of-a-fuchsia-package): A
  Fuchsia package is one or more collections of files that provide one or more
  programs, components or services for a Fuchsia system.
- Fuchsia library: An informal definition for implementation code used by
  Fuchsia, usually found in lib or lib/src directories. Libraries are a
  convention, most policies for libraries are enforced socially or fallback to
  language specific approaches and tooling.
- [Dart package](https://dart.dev/guides/packages): The Dart package system is
  used to share software like libraries and tools within the Dart ecosystem,
  e.g. via Pub. Often a package is a collection of files with a minimum of a
  pubspec.yaml file and at least one Dart file, in-tree Dart packages will also
  have a `BUILD.gn` file.
- [Dart library](https://dart.dev/tools/pub/package-layout#public-libraries): A
  collection of Dart code (classes, constants, typedefs, etc.) isolated to a
  single namespace and corresponding to a single entry point, e.g. `import
  'package:enchilada/enchilada.dart';` imports the enchilada library. Note that
  Dart libraries have a privacy boundary, e.g. private implementation details
  are not visible or accessible outside of the library. A Dart package can
  contain multiple Dart Libraries.

When writing Dart code it is important to understand the distinction in
terminology in order to remain clear when communicating with team members whose
primary language might be one of the other supported languages (C++, Rust,
etc.).

- A Fuchsia package can contain components implemented as Dart binaries.
- A Dart binary is defined within a Dart package, and often has dependencies on
  other Dart packages.
- Code shared as a library in Fuchsia’s tree written in Dart is implemented as a
  Dart package.

### Focus on the Interfaces

Public classes should expose a clean user interface that clearly describes the
API surface and is free from internal implementation details. Classes that
contain more than a minimal amount of functionality should expose their API in
an abstract class with the implementation inside a private implementation file.
Doing so allows for the users of the classes to focus on the public methods and
forces the implementer to think about the usage of the class before
implementation.

### Consider Composability

When designing the API consider how it will fit into the larger Dart ecosystem
of libraries. For example, if writing an API that delivers events, consider
using Streams instead of callbacks because they compose better with libraries
like Flutter.

## Lint Rules

Dart code written against the Fuchsia SDK should pass all the lint rules
specified by the
[analysis_options.yaml](https://fuchsia.googlesource.com/topaz/+/HEAD/tools/analysis_options.yaml)
file, which lives in the topaz repository. These lint rules will help to automate
the review API review process. There are situations where a lint rule may be in
conflict with a specific API and may need to be explicitly ignored. If a file is
opting out of a lint rule the developer must provide a comment explaining the
reasoning for opting out of the lint rule.

## Library Structure

When organizing the structure of a Dart package it is important to follow the
recommendations laid out by the [Effective
Dart](https://www.dartlang.org/guides/language/effective-dart) style guide.
Additionally, developers should consider how their code is exported. For a more
complicated package, developers should avoid a singular catch all top-level
export file and rather expose a top level file per logical grouping of classes
that make sense to be pulled under one import line. This allows users of the
library the ability to have finer grained control over which sections of the
library they import.

## Comments/Documentation

All comments should adhere to [Effective Dart:
Documentation](https://www.dartlang.org/guides/language/effective-dart/documentation)
as well as the [Fuchsia Documentation](documentation.md) guide.

## Dependencies

Packages written for the Dart Fuchsia SDK should not take on third party
dependencies that are not themselves also in the Fuchsia SDK. Exceptions will be
made for the following, well established, dependencies that are likely to be
present in all environments. Any packages that should be added to this list
must be approved by the [API
Council](/docs/contribute/governance/api_council.md).

- [logger](https://pub.dev/packages/logging)
- [meta](https://pub.dev/packages/meta)
- [intl](https://pub.dev/packages/intl)
- [flutter](https://flutter.dev/)


Packages that do take on external dependencies should consider whether they
want to reexport those symbols. If the dependency is reexported then the
generated documentation will generate documentation for the external dependency.
However, reexporting the dependency will create a tight coupling between package
versions.

## Formatting

Code should be formatted using `dart format`. This is an opinionated tool that
cannot be configured. Formatting all of our code with this tool will ensure
consistency. In Fuchsia, you can use `fx format-code` will run `dart format` on
all staged dart files.

## Files

- DO name files after their public class name
- PREFER placing each class into their own files, even if they’re private. It
  should be rare for multiple classes to live in the same file. Only private,
  small, simple and standalone classes can share a file with a public class.
- AVOID creating utility classes or libraries, these tend to turn into code
  dumping grounds. Instead, use precise naming that clearly communicates the
  purpose of the code being created.
- DON’T use the `part of` directive to avoid tight coupling of classes.

### Methods

- PREFER using named parameters vs positional parameters for public methods on
  public classes that have greater than 2 parameters. This aids code refactor
  and allowed adding extra parameters without breaking the public API contract.
- AVOID using functions that can do more than one thing like `void
  updateAndCommit();` but prefer explicit naming.

### Constructors

- PREFER using named parameters with Constructors that have more than two
  parameters.
- DO use the meta package to indicate which parameters are required.
- DO assert on required parameters.
- DO throw exceptions/errors for public APIs that will have detrimental side
  effects if invalid input is passed to constructors, since asserts do not run
  in release builds.

```
/// Constructs a [Car] object
///
/// If [id] is not provided one will be
/// generated with a UUID4 format.
Car({
  @required this.make,
  @required this.model,
  this.id,
}) : assert(make != null),
     assert(model != null);
```

## Naming
If a method will use a cached object, or create it if it doesn’t exist, avoid
introducing or into the name.

```
class Node {
  //BAD
  Node getOrCreateChild(String name);
              
  //GOOD
  Node child(String name);
}
```

When adding a function or interface that will have methods invoked in response
to another action, name the methods add<NAME>Listener() and
remove<NAME>Listener(). The objects that implement the <NAME>Listener interface
should name the invoked methods on<EVENT>.

```
class MediaController {
  void addMediaListener(MediaListener listener) {}
  void removeMediaListener(MediaListener listener) {}
}

abstract class MediaListener {
  void onPause();
  void onPlay();
}
```

When appending an item to your object prefer the name add<Name> instead of
append to follow the dart list naming.

When deciding between using a single member abstract or a plain `Function` as a
`Listener` object consider how your API might evolve over time. If you expect
that you may add more methods to the listener use a single member abstract to
allow for the evolution but if the API is not likely to change use a plain
function.

```
// This could logically grow to include an onDoubleTap()
// method so it makes sense to use a single member abstract.
abstract class TapListener {
  void onTap();
}
void addTapListener(TapListener listener) { ... } 

// This will likely never need more methods so it can 
// clearly take a function type.
void addOnCloseListener(void Function() listener) { ... }
```

## Preferred Types
Concrete data types should be used instead of lower level primitives. The
following types should be used when possible:

- [Duration](https://api.dartlang.org/stable/2.4.0/dart-core/Duration-class.html)
  when working with a span of time.
- [DateTime](https://api.dartlang.org/stable/2.4.0/dart-core/DateTime-class.html)
  when working with dates.

If there is not a concrete type that can be used to represent your object at a
higher level your API should expose one. For example, if we had an API that
dealt with currency we would create a `Currency` data type instead of working
with `num` types.

```
// BAD
int getCash() { ... }

// GOOD
Currency getCash() { ... }
```

Your API should avoid returning unstructured JSON data but rather transform any
JSON into a typed value.

```
// BAD
Map<String, dynamic> getCar() => {
    'make': 'Toyota',
    'year': 2019, 
}

// Good
Car getCar() => Car(make: 'Toyota', year: 2019);
```

## Internationalization
If a package exposes a user visible string the string should be
internationalized. In the absence of an ability to internationalize a user
visible string the API should return data in which a user of a library can
construct an internationalized string.

Exceptions and log messages do not need to be internationalized if they are not
intended to be user visible.

## Error Handling
All error handling should adhere to [Effective Dart: Error
handling](https://www.dartlang.org/guides/language/effective-dart/usage#error-handling).


## Error vs. Exception
Error and its subclasses are for programmatic errors that shouldn’t be
explicitly caught. An Error indicates a bug in your code, it should unwind the
entire call stack, halt the program, and print a stack trace so you can locate
and fix the bug.

Non-Error exception classes are for runtime errors. If your API implementation
throws an exception, it should be documented as part of the public API and it’s
expected behavior. This will facilitate programmatic handling of the exception
by API clients.

Except in a few special circumstances, idiomatic Dart should throw Errors, but
never catch them. They exist specifically to not be caught so that they take
down the app and alert the programmer to the location of the bug.

Note: often times people refer to Error when they mean Exception and vice versa.
Especially developers that are coming from a different language. Apply your
knowledge of their difference when developing your Dart API.

Your public API should throw well defined and typed exceptions so that users can
catch them and react appropriately. If you are not in control of all the code
that is being called by your package, maybe because you are using a third party
library, you may not be able to know exactly which exceptions may be thrown. If
this is the case, you can either attempt to catch the exception and wrap it in a
type that you create or clearly document that an exception of unknown type may
be thrown.

If your API can fail in more than one way the exception should clearly indicate
the failure method. Consider throwing different types of exceptions or adding a
code to the exception so the caller can respond appropriately. Also, don’t
forget to publicly document all the exceptions that are potentially thrown by a
given method.

```
enum ErrorCode { foo, bar }

class MyException implements Exception {
  final ErrorCode code;
  MyException(this.code);
}

/// Throws MyException(ErrorCode.foo) if condition is true or
/// throws MyException(ErrorCode.bar) if not 
void baz(bool condition) {
  If (condition) {
    throw MyException(ErrorCode.foo);
  } else {
    throw MyException(ErrorCode.bar);
  }
}
```

### Assertions vs. Exceptions
Assertions should only be used to verify conditions that should be logically
impossible to be false due to programmer error, not user or data input. These
conditions should only be based on inputs generated by your own code. Any checks
based on external inputs should use exceptions.

Use asserts when you are in full control of the inputs. For example verify
private functions' arguments with asserts, and using exceptions for public
functions arguments.

In Dart all assertions are compiled out from the production/release builds.
Therefore, your program must work just as well when all assertions are removed.
Do not directly assert on a value returned directly from a function as this can
cause the code to not be included in release build since the entire body of the
assert is removed in release builds.

```
// BAD
assert(foo()); // foo is not executed

// GOOD
final success = foo();
assert(success);
```

### FIDL Exception Handling
In Fuchsia, the generated Dart FIDL bindings are always asynchronous, thus all
methods return a `Future` even if there is no return value (`Future<void>` is
used). Also, when connecting to a particular service the connection is assumed
to be successful even though it can fail to connect or disconnect in the future.
For these reasons, the caller of any FIDL api should always assume that a
specific call can fail and handle that appropriately when needed.

```
final _proxy = fidl_myService.MyServiceProxy();
connectToService('fuchsia-pkg://fuchsia.com/my_service#meta/my_service.cmx', _proxy);

_proxy
  .doSomething()
  .catchError((e, s) {
    // handle the error if needed
  });
```

## Testing
Please review [Dart](https://www.dartlang.org/guides/testing) and
[Flutter](https://flutter.dev/docs/testing) testing guides.

- DO test for `Future<T>` when disambiguating a `FutureOr<T>` whose type
  argument could be Object.
- DON’T use `@visibleForTesting` on public API.

The API surface of your package should be well tested. However, the public API
should not need to leak internal details for the class to be testable. Consider
the following example:

```
class Foo {
  // services is exposed for testing
  Foo({GlobalServices services = GlobalServices()}) { … }

  // Connects to the global service with the given name.
  Connection connectToGlobalService(String name) {
     return services.connect(name);
  }
}
```

Rather, consider writing your class as an abstract class so the user does not
need to know about the injection of global services but tests can directly
inject the global services into the implementation. These avoids leaking
implementation details to the user and provides an API that the user cannot
abuse or mess up. This has the added advantage of allowing the API to evolve if
the GlobalServices class evolves without having to change the callers of the
method.

```
// foo.dart
abstract class Foo {
  factory Foo() => FooImpl(services: GlobalServices);
  connectToGlobalService(String name);
}

// internal/foo_impl.dart
class FooImpl implements Foo {
  FooImpl({GlobalServices services}) { … }

  // Connects to the global service with the given name.
  Connection connectToGlobalService(String name) {
     return services.connect(name);
  }
}
```

Dart does not allow a private class/function to be accessed from within a test.
This has the effect that any private classes cannot be tested. This may be ok if
there is a corresponding public class/function that can exercise the private
members but this may not always be the case. In these situations it is best to
move the private class into its own file, which does not get exported by the
top-level export, and make it public. The tests can now access your private
members.

```
/// BAD - this code does not make _Taco directly testable

// dinner.dart
class Dinner {
  final _taco = _Taco();
  
  void eat() => _taco.consume();
}

// We have no way to directly test this class
class _Taco {
  void consume() {}
}

/// GOOD - this code makes Taco directly testable by moving it to its own private file

// dinner.dart
import '_taco.dart';

class Dinner {
  final _taco = Taco();
  void eat() => _taco.consume();
}

// _taco.dart 
class Taco {
  void consume() {}
}

// _taco_test.dart
import 'package:dinner/src/_taco.dart' // ignore: implementation_imports

void main() {
  test('taco consumption', () {
    expect(_Taco().consume(), runsNormally);
  });
}
```

## Design Patterns
### Disallowing Subclassing
It can be useful for a library to declare a common base class without allowing
developers to extend the common base class. The common pattern for supporting
this is to declare a private constructor on your public base class. This has the
effect of allowing subclasses within the same file to extend the base class
while not allowing users of your library to subclass the base class.

```
/// Base class
abstract class A {
  // private constructor disallows instantiation outside of this file
  ._();
  /// Concrete implementation of foo
  void foo() {}
}

/// A concrete implementation of [A]
class B extends A {
  () : super._();

  @override
  void foo() {
    // B implementation
    super.foo();
  }
}
```

It is important to note that this pattern does not restrict users from
subclassing the child class since it has a public constructor. If this
restriction is required see the factory constructors pattern below.

This pattern is useful if the implementation surface is small since the pattern
requires all of the subclasses to live in the same file as the base class or to
use the part of directive, which is discouraged. If the surface area is too large
for a single file consider an alternate pattern.


### Factory Constructors

There are times when a user only needs to interact with a single interface but
which may have a different implementation depending on how the object was
constructed. Requiring the user to know about the different implementations can
add unnecessary APIs, and only serves to confuse the user. In this
situation you can define an abstract base class that defines the API surface
and create factory constructors that vend the appropriate private class.

```
// Publicly exported class
abstract class Foo {
  
  factory Foo() => FooImpl();

  factory Foo.withNamespace(String namespace) => NamespacedFoo(namespace);

  void update(String value);
  void revert();
}

// Private implementations not exported in public API
class FooImpl implements Foo {
  final _values = <String>[];

  @override
  void update(String name) => _values.add(name);

  @override
  void revert() => _values.removeLast();
}

class NamespacedFoo extends FooImpl {
  final String namespace;
  NamespacedFoo(this.namespace);

  @override
  void update(String name) => super.update('$namespace/$name');
}
```

Note: If you need to add the restriction that the base class cannot be extended
you can implement the pattern defined in Disallowing Subclassing that adds a
private constructor to the public base class

### Working with FIDLs

Try to make a clear distinction between regular object types and FIDL types.
This makes it easier for the maintainers of the code to identify FIDL types from
other types and take the necessary precautions when needed. Consider using the
as when importing a FIDL service and prefixing it with “fidl_”, this makes it
very to identify FIDL types across the entire file.

```
import 'package:fidl_fuchsia_foo/fidl_async.dart' as fidl_foo;

// now it is clear that the return type bar comes from fidl_foo
fidl_foo.Bar myMethod(String baz) {...} 
```

When subclassing FIDL types extend them so they can be interchanged with the
generated FIDL files. Usually, wrappers decorate the existing type with
additional functionality that compliments the original object. However, by
extending it from the original FIDL it allows the existing and new API to work
with original FIDL types instead of the more concrete types, which is useful when
interacting with other FIDLs or when developers are not using your wrapper.

### Decoupling implementation concerns

Try to avoid interfaces that cover multiple areas of concerns. By breaking down
the concerns users can have more flexibility with how they choose to combine the
interfaces and allows composed objects to be passed to methods with specific
concerns.

```
void main() {
  final restaurant = lookupRestaurant();
  map.display(restaurant);
  phone.call(restaurant);
}

abstract class Callable {
  String get phoneNumber;
}

abstract class Location {
  String get address;
  String get displayName;
}

class Restaurant implements Callable, Location {
  final String name;
  final String phoneNumber;
  final String address;
  String get displayName => name;

  Restaurant(this.name, this.phoneNumber, this.address);
}

class Map {
  void display(Location descriptor) {}
}

class Phone {
  void call(Callable callable) {}
}
```

### Iteration of Modifiable Collections
When exposing an API that can modify some sort of collection it is important to
protect against modifying the collection during iteration. When iterating over
an internal collection consider making a copy of the backing collection to
iterate. This will protect from exceptions being thrown for concurrent
modification of the underlying collection.

```
class Controller {
  final _listeners = <void Function()>[];
  void addListener(void Function() f) => _listeners.add(f);
  bool removeListener(void Function() f) => _listeners.remove(f);

  void notify() {
    // Make a copy to avoid modification of _listeners during iteration.
    for (final f in List.of(_listeners)) {
      // This method can safely call add/remove listeners
      f();
    }
  }    
}
```

## Anti Patterns

The following patterns should be avoided when writing Dart libraries for the
Fuchsia Dart SDK. Exposing Internal Details for Testing It may be tempting to
expose certain aspects of your API for testing concerns. However, doing so can
clutter your public interface and leak implementation details that the user
does not need to know about or may come to rely on. See the [Testing](#Testing)
section for more details

### Accepting/Returning dynamic Types

Dart provides a dynamic type for which the compiler will allow any type to be
passed to a function and returned from a function. This can be useful in some
situations like json encoding/decoding but in the general case it should be
avoided. Using dynamic types prevents the compiler from performing static type
checking at compile time and introduces hard to debug run-time errors.

In situations where an API might need to accept/return multiple input types
consider using generics or defining an interface that the object implements
instead. In situations where this will not work, consider defining multiple
methods that call through to the private dynamic accepting function.

### Using Private Methods Across Files

Dart distinguishes private members from public members by prefixing them with
the underscore. This creates isolation between files reduces coupling. This can
be overridden by using the `part of` directive at the top of a file. This
directive has the effect of combining multiple files and allowing them to access
each others private members. Doing this makes it hard to rationalize about what
is public and what is private and creates tight coupling between classes. Rather
than using this directive, it is recommended to only interact with another
object via its public interfaces. If classes must interact via private
interfaces it is recommended to keep them in the same file to clearly indicate
their relationship.

### Global Static Variables

Global static variables can be useful in sharing state across a library but they
can easily introduce race conditions and hard to debug code. Global variables
can also be accessed by users of your library, which may introduce unexpected
side effects. It is strongly recommended that you avoid global static variables
in public libraries.

If there is a reason that your package does need to use a global static variable
it is recommended to use zone-local static variables instead to isolate the
variable from users of your library.

```
void startComputation() {
  runZoned(() async {
    await collectScores(getValues());
    print('Scores: ${Zone.current[#scores]}');
  }, zoneValues: {#scores: <int>[]});
}

Future<void> collectScores(Stream<int> scores) async {
  await for (int value in scores) {
    Zone.current[#scores].add(value);
  }
}

// scores will not be affected by the call to startComputation.
final scores = <int>[1, 2, 3];

void main() {
  startComputation();
}
```
