Skip to content

Commit 38ffb10

Browse files
authored
add a section on omitted types and inference (#2160)
1 parent bb4ac9c commit 38ffb10

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

working/macros/feature-specification.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,59 @@ Allowing deep introspection like this in cases where a macro needs it while
5050
ensuring that users can understand the system and tools can implement it
5151
efficiently is a central challenge of this proposal.
5252

53+
#### Omitted Type Annotations and Inference
54+
55+
In general, the introspection APIs will only provide exactly what the user has
56+
written for the types of declarations. However, this presents problems when the
57+
type is omitted, and in particular when the type is omitted but a useful type
58+
would be inferred. For example, see this class:
59+
60+
```dart
61+
class Foo extends Bar {
62+
final inferred = someFunction();
63+
64+
final String name;
65+
66+
Foo(this.name, {super.baz});
67+
}
68+
69+
class Bar {
70+
final String? baz;
71+
72+
Bar({this.baz});
73+
}
74+
```
75+
76+
When introspecting on the `inferred` field, the `this.name` parameter, or the
77+
`super.baz` parameter, there is no hand written type to use. However, a macro
78+
may need to know the actual inferred type, in order to emit an equivalent type
79+
annotation in generated code elsewhere in the program.
80+
81+
In order to resolve this, there will be a special `OmittedTypeAnnotation`
82+
subtype of `TypeAnnotation`. It will have no fields, and is just a pointer to
83+
the place where the type annotation was omitted.
84+
85+
There are two things you can do with an `OmittedTypeAnnotation`:
86+
87+
- Pass it directly as a part of a `Code` object.
88+
- When the final augmentation library is created, the actual type that was
89+
inferred will be used (or `dynamic` if no type was inferred).
90+
- Explicitly ask to infer the type of it through the builder apis (only
91+
available in phase 3).
92+
- We don't allow augmentations of existing declarations to contribute to
93+
inference, so in phase 3 type inference can be performed.
94+
95+
This allows you to generate correct signatures for any declarations you need to
96+
create in Phase 1 or 2, without actually performing inference in those phases.
97+
At the same time it allows you to get the inferred type in phase 3, where you
98+
are creating the bodies of functions and may need to know the actual inferred
99+
type (for instance you might want to do something for all fields that implement
100+
a given interface).
101+
102+
The primary limitation of this approach is that you will not be able to inspect
103+
the actual types of declarations where the type was omitted prior to phase 3,
104+
but this situation will also be made very explicit to macro authors.
105+
53106
### Ordering in metaprogramming
54107

55108
Macros can read the user's Dart program and modify it. They are also written in

0 commit comments

Comments
 (0)