I need to use reflectable on a third party lib but it is not working.
Consider this scenario:
Library A has the reflector declaration:
class Reflector extends Reflectable {
const Reflector()
: super(invokingCapability,
typeRelationsCapability,
metadataCapability,
superclassQuantifyCapability,
reflectedTypeCapability);
}
const Reflector reflector = const Reflector();
Library B has the classes that are annotated with the reflector:
import 'package:library_a/library_a.dart' show reflector;
@reflector
class whateverz {}
Now the application C needs to use reflection on whateverz class that is within library B.
My problem is that the reflectable lib can't see the whateverz class annotated. The build warns "reflector.dart: This reflector does not match anything"
And if I do "print(reflector.annotatedClasses);" it prints [] within the console.
Is this possible? To annotate the classes on a third party lib that I will end up using in an application with reflection? If yes, what am I doing wrong?
I suspect that the transformation isn't being performed on the correct main file.
The transformer is capable of looking up any declaration in your program, so if there is a library in your program which is importing library B (and hence also library A) then the transformer should certainly be able to generate a mirror for class whateverz
, and you should find that mirror in reflector.annotatedClasses
.
But the set of files taken into account during transformation is the transitive closure of the imports from your entry point (that is, the relevant element in the entry_points
specified in your pubspec.yaml
), so if you specify an entry point which is not the actual main file then the transformer may get to work with a smaller (or just different) set of libraries. For instance, if you use library A as the entry point then the transformer won't know that library B exists (assuming that library A doesn't directly or indirectly import library B), so the transformer won't discover any declarations in library B and you won't get the corresponding mirrors.
If you are working on a library that other developers will import and use, you need to tell them to include the reflectable transformer in their pubspec.yaml
and add an element to the entry_points
(or check that they are using a wildcard that already matches all the desired entry points).
You can check out three_files_test.dart to see a tiny example where a reflector in one file is used to annotate classes in different files, and you can check out meta_reflectors_test.dart to see how you can decouple reflectors, target classes, and other elements even more (e.g., by using GlobalQuantifyCapability
to associate a certain reflector with a certain target class without editing the file that contains the target class).