@@ -908,68 +908,58 @@ has two colliding declarations.
908
908
909
909
#### Shadowing declarations
910
910
911
- All the rules below apply only to the library in which a macro is
912
- applied&mdash ; macro applications in imported libraries are considered to be
913
- fully expanded already and are treated exactly the same as handwritten code.
914
-
915
911
Macros may add member declarations that shadow top-level declarations in the
916
- library. When that happens, we want to ensure that the intent of the
917
- user-written code is clear . Consider the following example:
912
+ library. When that happens, we have to choose how references to that shadowed
913
+ member resolve . Consider the following example:
918
914
919
915
``` dart
920
916
int get x => 1;
921
917
922
918
@GenerateX()
923
919
class Bar {
924
- // Generated: int get x => 2;
920
+ // Generated
921
+ int get x => 2;
925
922
926
923
// Should this return the top level `x`, or the generated instance getter?
927
924
int get y => x;
928
925
}
929
926
```
930
927
931
- There are several potential choices we could make here:
932
-
933
- 1 . Any identifier that can be resolved before macro application keeps its
934
- original resolution. Here, ` x ` would still resolve to the original,
935
- top-level variable.
936
-
937
- 2 . Re-resolve all identifiers after macros are applied, which may change what
938
- they resolve to. In the example here, ` x ` would re-resolve to the generated
939
- instance getter ` x ` .
928
+ In this situation, resolution is done based on the final macro generated code,
929
+ as if it was written by hand. Effectively, this means that resolution of bodies
930
+ must be delayed until after macro execution is complete.
940
931
941
- 3 . Make it a compile-time error for a macro to introduce an identifier that
942
- shadows another .
932
+ This (mostly) avoids the need for resolving method bodies multiple times, and
933
+ also means that all macro code could be replaced with a hand-authored library .
943
934
944
- 4 . Make it a compile-time error to * use* an identifier shadowed by one produced
945
- by a macro.
935
+ ##### Constant evaluation, Identifiers, and shadowed declarations
946
936
947
- The first two choices could be very confusing to users, some will expect one
948
- behavior while others expect the other. The third choice would work but might be
949
- overly restrictive. The final option still avoids the ambiguity, and is a bit
950
- more permissive than the third, so we take that approach .
937
+ Given that constant evaluation can be attempted in any phase, it is possible for
938
+ it to return a _ different result _ for the same piece of code between phases. In
939
+ particular the types phase and declaration phase may introduce declarations
940
+ which shadow previously resolved identifiers from other libraries .
951
941
952
- It's also possible that a top-level declaration and an instance declaration that
953
- shadows it are * both * produced by macros. If we resolved a hand-written
954
- identifier with the same name at different points during macro expansion, it
955
- might refer to different macro-generated declarations. That would also be
956
- confusing, and we don't want to allow that .
942
+ If this happens, it would always cause a constant evaluation failure in the
943
+ later phase, since identifiers from the current [ strongly connected component ] [ ]
944
+ are not allowed during const evaluation. This is not enough however to catch all
945
+ situations, because a macro may not attempt const evaluation at that point, and
946
+ could have previously gotten an incorrect result .
957
947
958
- These constraints produce this rule: It is a compile-time error if any
959
- hand-authored identifier in a library containing a macro application would bind
960
- to a different declaration when resolved before and after macro expansion in
961
- that library.
948
+ Similarly, a Code object provided as a part of a metadata annotation argument
949
+ may have Identifiers which were originally resolved to one declaration, and then
950
+ later resolved to a different declaration.
962
951
963
- This follows from the general principle that macros should not alter the
964
- meaning of existing code. Adding the getter ` x ` in the example above shadows the
965
- top-level ` x ` , changing the meaning of the original code.
952
+ In order to resolve these discrepancies we add this rule:
966
953
967
- Note, that if the getter were written as ` int get y => this.x; ` , then a macro
968
- * would* be allowed to introduce the new getter ` x ` , because ` this.x ` could not
969
- previously be resolved.
954
+ - ** It is a compile time error for a macro to add a declaration which shadows**
955
+ ** any previously resolved identifier.** . These errors occur after a macro
956
+ runs, when the compiler is merging in the macro results, and so it is not
957
+ catchable or detectable by macros.
970
958
971
- ** TODO** : Revisit this to see if it aligns with the scoping rules of compiling
972
- macros to library augmentations.
959
+ This situation can typically only happen because of one of the above scenarios
960
+ surrounding metadata annotations or const evaluation, and can typically be
961
+ resolved by adding an import prefix. To force resolution to the generated symbol
962
+ in the current library, a library can import itself with a prefix.
973
963
974
964
#### Resolving identifiers in generated code
975
965
0 commit comments