# Pragma Annotations understood by dart2js

## Pragmas for general use

| Pragma | Meaning |
| --- | --- |
| `dart2js:noInline` | [Never inline a function or method](#requesting-a-function-never-be-inlined) |
| `dart2js:never-inline` | Alias for `dart2js:noInline` |
| `dart2js:tryInline` | [Inline a function or method when possible](#requesting-a-function-be-inlined) |
| `dart2js:prefer-inline` | Alias for `dart2js:tryInline` |
| `dart2js:disable-inlining` | [Disable inlining within a method](#disabling-inlining) |
| `dart2js:noElision` | Disables an optimization whereby unused fields or unused parameters are removed |
| `dart2js:load-priority` | [Affects deferred library loading](#load-priority) |
| `dart2js:resource-identifier` | [Collects data references to resources](resource_identifiers.md) |
| `dart2js:stack-starts-at-throw` | [Affects stack trace from `throw` expressions](#stack-statrs-at-throw) |
| `weak-tearoff-reference` | [Declaring a static weak reference intrinsic method.](#declaring-a-static-weak-reference-intrinsic-method) |

## Unsafe pragmas for general use

These pragmas are available for use in third-party code but are potentially
unsafe. The use of these pragmas is discouraged unless the developer fully
understands potential repercussions.

| Pragma | Meaning |
| --- | --- |
| `dart2js:as:check` | [Check `as` casts](#casts) |
| `dart2js:as:trust` | [Trust `as` casts](#casts) |
| `dart2js:downcast:check` | [Check downcasts](#downcasts) |
| `dart2js:downcast:trust` | [Trust downcasts](#downcasts) |
| `dart2js:index-bounds:check` | TBD |
| `dart2js:index-bounds:trust` | TBD |
| `dart2js:late:check` | [Check late fields are used correctly](#late-checks) |
| `dart2js:late:trust` | [Trust late fields are used correctly](#late-checks) |
| `dart2js:parameter:check` | TBD |
| `dart2js:parameter:trust` | TBD |
| `dart2js:types:check` | TBD |
| `dart2js:types:trust` | TBD |
| `dart2js:allow-cse` | [Allow common subexpression elimination (CSE)](#allow-cse) |
| `dart2js:allow-dce` | [Allow dead code elimination (DCE)](#allow-dce) |

## Pragmas for internal use

These pragmas can cause unsound behavior if used incorrectly and therefore are
only allowed within the core SDK libraries.

| Pragma | Meaning |
| --- | --- |
| `dart2js:assumeDynamic` | TBD |
| `dart2js:disableFinal` | TBD |
| `dart2js:noSideEffects` | Requires `dart2js:never-inline` to work properly |
| `dart2js:noThrows` | Requires `dart2js:never-inline` to work properly |

## Detailed descriptions

### Annotations related to function inlining

Function (method) inlining is a compiler optimization where a call to a function
is replaced with the body of the function.  To perform function inlining, the
compiler needs to determine that the call site calls exactly one function, the
target.  This is trivial for top-level methods, static methods and
constructors. For calls to instance methods, the compiler does an analysis of
the possible types of the receiver and uses that to reduce the set of potential
targets. If there is a single target, it can potentially be inlined.

Not all functions can be inlined. For example, a recursive function cannot be
expanded by inlining indefinitely. `dart2js` will not inline functions complex
control flow, such as methods with exception handling (`try`-`catch`-`finally`)
or many return or throw exit points.

We say a function is a _viable inlining candidate_ when it is the single target
and it is possible to perform the inlining.

One benefit of inlining is that the execution cost of performing the call is
avoided, which can be a substantial part of the total cost of the call when the
body of the callee is simple.  Copying instructions from the callee into the
caller can create more opportunities for optimization, for example, it becomes
possible to recognize and remove repeated operations.

The compiler automatically makes a decision whether or not to inline a function
or method based on heuristics. One heuristic is to inline if the inlined
code is likely to be smaller that the call, as this results in a smaller _and_
faster program. Another heuristic is to inline even if the code is likely to be
slightly larger when the call is in a loop, as loops here is a chance that some
of the code can be hoisted out of the loop.

The annotations described below allow the developer to override the default
decisions. They should be used sparingly since it is likely that over time
manual overrides will become increasingly out of date and mismatched with the
evolving capabilities of the compiler.

#### Requesting a function be inlined

```dart
@pragma('dart2js:tryInline')
```

```dart
@pragma('dart2js:prefer-inline') // Alias for the above annotation.
```

This annotation may be placed on a function or method.

The compiler will inline the annotated function wherever it is a viable inlining
candidate.


#### Requesting a function never be inlined

```dart
@pragma('dart2js:noInline')
```

```dart
@pragma('dart2js:never-inline') // Alias for the above annotation.
```

This annotation may be placed on a function or method to prevent the function
from being inlined.

#### Disabling inlining

```dart
@pragma('dart2js:disable-inlining')
```

This annotation may be placed on a function or method.

Function inlining is disabled at call sites within the annotated function.
Inlining is disabled even when the call site has a viable inlining candidate
that is annotated with `@pragma('dart2js:prefer-inline')`.


### Annotations related to run-time checks

The Dart language and runtime libraries mandate checks in various places. Checks
result in some kind of `Error` exception being thrown.  If a program has a high
degree of test coverage, the developer might have some confidence that the
checks will never fail. If this is the case, the checks can be disabled via
command line options or annotations. Annotations override the command line
settings.

Trusting (i.e. disabling) checks can lead to a smaller and faster program.  The
cost is highly confusing unspecified behavior in place of the `Error`s that
would otherwise have been thrown. The unspecified behavior is not necessarily
consistent between runs and includes the program execution reaching statements
that are 'impossible' to reach and variables being assigned values of an
'impossible' type.

#### Casts

```dart
@pragma('dart2js:as:check')
@pragma('dart2js:as:trust')
```

These annotations may be placed on a function or method to control whether `as`
casts in the body of the function are checked.

One use of `dart2js:as:trust` is to construct an `unsafeCast` method.

```dart
@pragma('dart2js:prefer-inline')
@pragma('dart2js:as:trust')
T unsafeCast<T>(Object? o) => o as T;
```

The `prefer-inline` pragma ensures that the function is inlined, removing the
cost of the call and passing the type parameter `T`, and the `as:trust` pragma
removes the code that does the check.

#### Downcasts

```dart
@pragma('dart2js:downcast:check')
@pragma('dart2js:downcast:trust')
```

These annotations may be placed on a function or method to control whether
implicit downcasts in the body of the function are checked.

This is similar to the `dart2js:as:check` and `dart2js:as:trust` pragmas except
it applies to implicit downcasts. Implicit downcasts are `as` checks that are
inserted to cast from `dynamic`.

The `unsafeCast` method described above could also be written by trusting
implicit downcasts.

```dart
@pragma('dart2js:prefer-inline')
@pragma('dart2js:downcast:trust')
T unsafeCast<T>(dynamic o) => o; // implicit downcast `as T`.
```

Trusting implicit downcasts is part of the `-O3` and `-O4` optimization level
command line options. `dart2js:downcast:check` can be used to enable checking of
implicit downcasts in a method when it would otherwise be trusted due to the
command line options.

#### Late checks

Late checks - checking whether a late variable has been initialized - occur on
all late variables.  The checks on late instance variables (i.e. late fields)
can be controlled via the following annotations.

```dart
@pragma('dart2js:late:check')
@pragma('dart2js:late:trust')
```

These annotations may be placed on the declaration of a late field, class, or
library. When placed on a class, the annotation applies to all late fields of
the class. When placed on a library, the annotation applies to all late fields
of all classes in the library. `dart2js:late` annotations are _scoped_: when
there are multiple annotations, the one nearest the late field wins.

In the future this annotation might be extended to apply to `late` local
variables, static variables, and top-level variables.


#### Stack starts at throw

In order to generate smaller code, `throw` expressions are usually implemented
by calling a helper method to capture the stack trace and perform the actual
throw. This adds one (or occasionally two) frames to the stack trace showing the
helper functions. It is possible for the stack trace to be captured directly in
the method containing the `throw` expression. This takes a little extra code, so
is opt-in via the following annotation.

```dart
@pragma('dart2js:stack-starts-at-throw')
```

This annotation can be placed on a method, class or library.

### Annotations related to compiler optimizations

#### Allow CSE

**EXPERIMENTAL**: This annotation may be removed without notice.

This annotation may be placed on a method or getter. If, after some
optimization, there are two calls to the same annotated method or getter, and
the calls have the same input values, and the first call will always have
happened by the time control flow reaches the second call, the compiler may
choose to remove the second call and use the value returned by the first call
instead.

```dart
@pragma('dart2js:allow-cse')
```

This annotation is intended for an `external` getter or method that always
refers to the same thing.

#### Allow DCE

**EXPERIMENTAL**: This annotated may be removed without notice.

This annotation may be placed on a method or getter. If the result of the call
to the method or getter is unused (or becomes unused due to other
optimizations), the compiler may choose to remove the call.

```dart
@pragma('dart2js:allow-dce')
```

This annotation is intended for and `external` getter or method that makes no
observable change.

### Annotations related to deferred library loading

#### Load priority

**This is not fully implemented.** The annotation exists but **has no effect**.


```dart
@pragma('dart2js:load-priority', option)
```
Provides a string argument `option` forwarded to the `dartDeferredLibraryLoader`
as the `loadPriority` argument.

These annotations may be placed on the import specification to change
the priority for all calls to `prefix.loadLibrary()`.

The annotation may also be placed closer to the `loadLibrary()` call.  When
placed on a method, the annotation affects all calls to
`prefix.loadLibrary()` inside the method.

When placed on a local variable, the annotation affects all calls to
`prefix.loadLibrary()` in the initializer of the local variable. In the
following example, only `prefix2` is loaded with high priority because of the
annotation on the variable called "`_`":

```dart
    await prefix1.loadLibrary();
    @pragma('dart2js:load-priority', 'someArg')
    final _ = await prefix2.loadLibrary();
    await prefix3.loadLibrary();
```

`dart2js:load-priority` annotations are _scoped_: when there are multiple
annotations, the one on the nearest element enclosing the call to
`loadLibrary()` is in effect.

### Declaring a static weak reference intrinsic method

```dart
@pragma('weak-tearoff-reference')
T Function()? weakRef<T>(T Function()? x) => x;
```

Declares a special static method `weakRef` which can be used to create weak references
to tearoffs of static methods. Weak reference declaration should be a static method taking
one positional required argument. Its return type should be nullable and should match
argument type. It should be either `external` or return its argument (for backwards compatibility).

Compiler replaces `weakRef(foo)` expression with either `foo` if method `foo()` is used and retained during
tree shaking, or `null` if `foo()` is only used through weak references.
Target `foo` should be a constant tearoff of a static method without arguments.
