@@ -87,7 +87,7 @@ There are two things you can do with an `OmittedTypeAnnotation`:
87
87
file as the macro annotation, so they can always do this.
88
88
- When the final augmentation library is created, the actual type that was
89
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
90
+ - Explicitly ask to infer the type of it through the builder APIs (only
91
91
available in phase 3).
92
92
- We don't allow augmentations of existing declarations to contribute to
93
93
inference, so in phase 3 type inference can be performed.
@@ -658,9 +658,9 @@ constructors are invoked, and their limitations.
658
658
types in the user code instantiating the macro are not necessarily present
659
659
in the macros own transitive imports.
660
660
661
- * Note: The Macro API is still being designed, and lives [ here] [ api ] .*
661
+ * Note: The Macro API is still being designed, and lives [ here] [ API ] .*
662
662
663
- [ api ] : https://github.com/dart-lang/sdk/blob/main/pkg/_fe_analyzer_shared/lib/src/macros/api.dart
663
+ [ API ] : https://github.com/dart-lang/sdk/blob/main/pkg/_fe_analyzer_shared/lib/src/macros/api.dart
664
664
665
665
### Writing a Macro
666
666
@@ -716,7 +716,7 @@ return results. For instance when generating a constructor, a macro will likely
716
716
just iterate over the fields and create a parameter for each.
717
717
718
718
We need generated augmentations to be identical on all platforms for all the
719
- same inputs, so we need to have a defined ordering when introspection apis are
719
+ same inputs, so we need to have a defined ordering when introspection APIs are
720
720
returning lists of declarations.
721
721
722
722
Therefore, whenever an implementation is returning a list of declarations, they
@@ -736,41 +736,59 @@ to introspect over non-macro metadata annotations applied to declarations.
736
736
For example, a ` @JsonSerialization() ` class macro might want to look for an
737
737
` @unseralized ` annotation on fields to exclude them from serialization.
738
738
739
- ** TODO ** : The following subsections read more like a design discussion that a
740
- proposal. Figure out what we want to do here and rewrite ( # 1930 ) .
739
+ Some macros may need to evaluate the real values of metadata arguments, while
740
+ others may only need the ability to emit that same code back into the program .
741
741
742
742
#### The annotation introspection API
743
743
744
- We could try to give users access to an actual instance of the annotation, or
745
- we could give something more like the [ DartObject ] [ ] class from the analyzer .
744
+ All declarations which can be annotated will have an
745
+ ` Iterable<MetadataAnnotation> get metadata ` getter .
746
746
747
- [ DartObject ] : https://pub.dev/documentation/analyzer/latest/dart_constant_value/DartObject-class.html
747
+ All ` MetadataAnnotation ` objects have a ` Code get code ` getter, which gives
748
+ access to the annotation as a ` Code ` object.
749
+
750
+ In addition, there will be two subtypes of ` MetadataAnnotation ` :
751
+
752
+ - ` IdentifierMetadataAnnotation ` : A simple const identifier, has a single
753
+ ` Identifier get identifier ` getter.
754
+ - ` ConstructorMetadataAnnotation ` : A const constructor invocation. This will
755
+ have the following getters:
756
+ - ` Identifier get type `
757
+ - ` Identifier get constructor `
758
+ - ` Arguments get arguments `
759
+ - The ` Arguments ` class will provide access to the positional and named
760
+ arguments as separate ` Code ` objects.
748
761
749
- Since annotations may contain references to types or identifiers that the macro
750
- does not import, we choose to expose a more abstract API (similar to
751
- [ DartObject] [ ] ).
762
+ For any macro which only wants to emit code from annotations back into the
763
+ program, these ` Code ` objects are sufficient.
752
764
753
- ** TODO** : Define the exact API.
765
+ For a macro which wants to access the actual _ value_ of a given argument or
766
+ the metadata annotation as a whole, they can evaluate ` Code ` instances as
767
+ constants (see next section).
754
768
755
- #### Annotations that require macro expansion
769
+ ### Constant evaluation
756
770
757
- This could happen if the annotation class has macros applied to it, or if
758
- some argument(s) to the annotation constructor use macros .
771
+ Macros may want the ability to evaluate constant expressions, in particular
772
+ those found as arguments to metadata annotations .
759
773
760
- Because macros are not allowed to generate code that shadows an identifier
761
- in the same library, we know that if an annotation class or any arguments to it
762
- could be resolved, then we can assume that resolution is correct.
774
+ We expose this ability through the ` DartObject evaluate(Code code) ` API, which
775
+ is available in all phases, with the following restrictions:
763
776
764
- This allows us to provide an API for macro authors to attempt to evaluate an
765
- annotation in _ any phase_ . The API may fail (if it requires more macro
766
- expansion to be done), but that is not expected to be a common situation. In
767
- the case where it does fail, users should typically be able to move some of
768
- their code to a separate library (which they import). Then things from that
769
- library can safely be used in annotations in the current library, and evaluated
770
- by macros.
777
+ - No identifier in ` code ` may refer to a constant which refers to any
778
+ system environment variable, Dart define, or other configuration which is not
779
+ otherwise visible to macros.
780
+ - All identifiers in ` code ` must be defined outside of the current
781
+ [ strongly connected component] [ ] (that is, the strongly connected component
782
+ which triggered the current macro expansion).
771
783
772
- Evaluation must fail if there are any macros left to be expanded on the
773
- annotation class or any arguments to the annotation constructor.
784
+ The ` DartObject ` API is an abstract representation of an object, which can
785
+ represent types which are not visible to the macro itself. It will closely
786
+ mirror the [ same API in the analyzer] [ DartObject ] .
787
+
788
+ The call to ` evaluate ` will throw a ` ConstantEvaluationException ` if the
789
+ evaluation fails due to a violation of one of the restrictions above.
790
+
791
+ [ DartObject ] : https://pub.dev/documentation/analyzer/latest/dart_constant_value/DartObject-class.html
774
792
775
793
#### Are macro applications introspectable?
776
794
@@ -1088,7 +1106,7 @@ a Dart program containing macro applications:
1088
1106
1089
1107
Starting at the entrypoint library, traverse all imports, exports, and
1090
1108
augmentation imports to collect the full graph of libraries to be compiled.
1091
- Calculate the [ strongly connected components ] [ ] of this graph. Each component is
1109
+ Calculate the [ strongly connected component ] [ ] s of this graph. Each component is
1092
1110
a library cycle, and the edges between them determine how the cycles depend on
1093
1111
each other. Sort the library cycles in topological order based on the connected
1094
1112
component graph.
@@ -1101,7 +1119,7 @@ library cycle, it is guaranteed that all macros used by the cycle have already
1101
1119
been compiled. Also, any types or other declarations used by that cycle have
1102
1120
either already been compiled, or are defined in that cycle.
1103
1121
1104
- [ strongly connected components ] : https://en.wikipedia.org/wiki/Strongly_connected_component
1122
+ [ strongly connected component ] : https://en.wikipedia.org/wiki/Strongly_connected_component
1105
1123
1106
1124
#### 2. Compile each cycle
1107
1125
@@ -1560,7 +1578,7 @@ resources outside of `lib`, which has both benefits and drawbacks.
1560
1578
1561
1579
** TODO** : Evaluate APIs for listing files and directories.
1562
1580
1563
- ** TODO** : Consider adding ` RandomAccessResource ` api .
1581
+ ** TODO** : Consider adding ` RandomAccessResource ` API .
1564
1582
1565
1583
The specific API is as follows, and would only be available at compile time:
1566
1584
0 commit comments