Does it already know how to do reflection for classes that you don't have access to?
Those classes to which you cannot add metadata to mark them for reflection?
Reflectable code generation is intended to be applied to an entry point, that is, a library that exports a function named `main` and whose transitive import closure defines the contents of "a program". So let's call that a 'program'.
This is of course a limitation (you can't run reflectable code generation on a library L in isolation and have it produce, say, support for reflection on all subtypes of a given class declared in L, because some of those subtypes may be declared in libraries that aren't part of the transitive imports from L). You could also say that reflectable relies on a closed world assumption.
However, if you do run reflectable code generation on a library whose transitive imports will be just part of any given program, you will get support for the requested level of reflection for that part. This means that you could request reflection support for all subtypes of a given class C, and you will actually get support for only some of them (the ones that we can "see" via direct or indirect imports). If you're happy about that level of support and want to do this then go ahead and use that approach.
However, the main scenario is still that reflectable code generation is applied to a program as a whole. This means that if you encounter an instance of a class C at runtime, the program will include a library that contains the declaration of C, and reflectable code generation will provide the requested level of reflection support.
The addition of metadata is not crucial: For instance, if you request reflection for all subtypes of a given type then there is no need to edit each library that contains a declaration of any such subtype. You can also specify that a specific level of support for reflection (a specific 'reflector') should be used with a specific declaration. You have to do this in some cases, e.g., if you wish to reflect on instances of `int` or other built-in classes, because you don't get to edit 'dart:core'. You would then associate that class with that reflector using a global quantifier like this one:
In short: If your workflow allows for using a closed world assumption then reflectable code generation can provide reflection for any declaration in your program.
Let's say I'm generating classes using tool.
This tool is not able to add metadata to generated classes.
What is wrong with using this tool?
There is nothing wrong.
But would the "reflectable" package be useful in this case?
I don't think so.
Maybe I'm wrong?
You'd run that tool T first, and then run the reflectable code generator. You would use quantification (a subtype quantifier, or a global quantifier, or one of the several other kinds) to request specific kinds of reflection support for specific declarations in generated libraries. You may also be able to make T generate code where the appropriate declarations have some metadata, and then you can tell reflectable to associate those declarations with a specific reflector:
@GlobalQuantifyMetaCapability(MyMetadata, reflector)
which will ensure that any declaration that has metadata which is an instance of `MyMetadata` or a subtype thereof gets the level of reflection support that `reflector` specifies.
Reflectable code generation does have some additional limitations, though: It is not possible to generate code in Dart that looks up the value of a type argument and makes that value available for the creation of new entities. For instance, you may have a variable of type `List<Widget>` whose value has dynamic type `List<SpecialWidget>`, but you can't use code-generation-based reflection to learn that the type argument is `SpecialWidget`, and you can't create a new `Map<String, SpecialWidget>` based on that fact.
Another limitation is that generated code has no way to determine the details of the type of a given function object (for instance, we can't obtain a list of names of named arguments accepted by a given function). We do have support for reporting the named arguments and such when it comes to a declaration (so you reflect on a class and iterate over its instance methods and investigate their formal parameters: no problem), but we do not have support for introspection on a function object at runtime.
The general issue is that we'd need a few more primitives in order to support these kinds of reflection, that is, we'd need a specialized, low-level version of a tiny portion of 'dart:mirrors'. It's not obvious how costly that would be, in terms of code size and performance.
In summary, the picture is somewhat complex, but you certainly can't just say that reflectable can't handle a class unless it's possible to edit its declaration and add some metadata to it.