dart-lang / dart-lang/language

Statement metadata

Open
#1,652 15 comments 3 reactions 0 assignees View on GitHub
feature
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

Dart currently allows metadata annotations (`@foo` or `@Foo(args)`, or even `@Foo(args)` soon) on *declarations*.
That makes sense if the primary way to access metadata is through `dart:mirrors`, and you can't mirror something you can't name.
However, annotations are also used by source-processing tools like the analyzer and some code generators. They can find annotations anywhere in the source.

Assume that we would want to allow metadata annotations on *statements* in general.

Annotations have no semantic effect on the Dart program itself, so it's all about sending signals to tools. Say, to tell the analyzer to disable a lint.

## Syntax
The syntax for annotations is currently `@id`, `@SomeClass(args)` or (soon) `@SomeClass(args)`.

The things you want to express for statements are not different from what you want to express for declarations, so it would be nice if all these annotations would be allowed on statements.
That's a problem, though, because it introduces grammar ambiguities if we just put the annotation before the statement, because an expression-statement allows almost any expression to follow it. Example:
```dart
@foo (a + b) [c];
```
this can be parsed as the annotation constructor invocation `@foo(a+b)` on the expression statement `[c];` *or* the annotation identifier `@foo` on the expression statement `(a+b)[c];`
Adding more parentheses to the expression is not necessarily a solution which scales (although if we disallow annotations on the *empty statement*, `;`, then `@foo((a + b)[c]);` can only be parsed in one way).

I'd recommend introducing a separator. Just like statement *labels* need a `:`, we could say that statement annotations need a `:`, and you have to write one of:
```dart
@foo:(a + b)[c];
@foo(a + b):[c];
```
That also suggests a formatting style where the annotation, like the label, is placed above the statement:
```dart
@foo(a+b):
[c];
```
Formatting issues are handled by treating statement annotations *exactly* like we treat labels.

That might be confusing when compared to existing annotations on local functions (which we allow), which don't need the trailing `:`:
```dart
@foo
int bar(int x) => x;
```
We may want to *allow* that annotation to have a `:` too, when it occurs inside a member body.

This suggests allowing the `` production where we could otherwise add a label.

## Expression annotations
With a delimiter like `@...:` for annotations, we could potentially also allow annotations on *expressions*.
It's more complicated because expressions have precedence, so `@foo:a + b` could mean `(@foo: a) + b` or `(@foo:(a+b))`.
If we put annotations on the expression itself, so it can contain *any* expression, then you can always parenthesize the scope you want, `(@foo: any+expression)`.
It's an ambiguity with statement annotations for `@foo:expr;`, but we can just always consider that a statement annotation and make you write `(@foo:expr);` if you want it on the expression.
In practice, you probably always want to parenthesize, so the maybe only allow it just inside parentheses. Change:
```
::= ...
| `(' expression `)'
...
primary ::= ...
| `(' * `')
```

## Summary
Allow a metadata production followed by a colon everywhere we allow a statement label.
Possibly, allow any number of metadata productions followed by colons (or just one colon?) inside at the start of a parenthesized expression.

I believe the grammar and parsing should be manageable.

Contributor guide

Open the contributing guide

Research direction

Start with the statement-label grammar discussion and the proposed metadata-with-colon examples in this issue, then compare the separate parenthesized-expression proposal. Done means reaching and documenting a decision on statement annotations, including whether expression annotations and colons on local-function annotations are supported.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.