dart-lang / dart-lang/language
Statement metadata
- 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
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