google / reflectable.dart

Reflectable is a Dart library that allows programmers to eliminate certain usages of dynamic reflection by specialization of reflective code to an equivalent implementation using only static techniques. The use of dynamic reflection is constrained in order to ensure that the specialized code can be generated and will have a reasonable size.

Home Page:https://pub.dev/packages/reflectable

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Depth of Reflection

viniciusandd opened this issue · comments

I have a scenario where many classes (widgets) will be reflected. My goal is to get the types of attributes of these classes. The amount of classes I intend to reflect requires my regex to be flexible and the consequence is the reflection of many unnecessary classes.

I believe that defining depth for reflection would solve my problem. Is there any way to do this?

depth for reflection

What would that mean?

Basically delimit the generated reflections.

An example would be generating A (I want its attributes) and B (as it is the type of the secondAttr attribute). But ignore C, as I won't be using B attributes.

class A {
  final int firstAttr;
  final B secondAttr;
}

class B {
  final C anyAttr;
}

class C {
  ...
}

In my use case I have control over the classes involved, but not over all types of attributes present in them.

This lack of predictability prevents me from controlling reflections through GlobalQuantifyCapability.

I can't replicate what you did here

Presumably you can't edit the target classes, and that's the reason why you are using GlobalQuantifyCapability?

In any case, the whole capability system has been introduced exactly in order to support a somewhat detailed kind of control over the extent to which there is support for reflection with various program entities. So there are lots of things you can do.

First, a regular expression can list alternatives, so there's nothing that prevents using a regular expression like ^my_library.(A|B)$ which will match class A and class B from a library that has the library directive library my_library;. This will instruct the reflectable code generator to support reflection for instances of A and B, but not C.

You may have some difficulties making that regexp precise enough if the given libraries don't have a library directive, because then you can't specify the libraries (and then an \.A$ would match any class named A, in any library).

Next, if you want to support reflection for a class like B implicitly because A contains a member whose signature mentions B then you'd use typeAnnotationQuantifyCapability in your reflector, or TypeAnnotationQuantifyCapability(transitive: true). The latter as quite aggressive, because you can easily get to a large number of classes if you use the transitive closure of classes that are reachable in this sense.

I noticed that Flutter uses a few library directives, but in some cases (like widget.dart) the library itself doesn't contain all the declarations that it provides, it just has a lot of export directives from some other libraries, and this means that you can't use ^widgets.SomeWidget$ to select it. But SomeWidget$ should still select the desired class, and if you don't include too many other classes with the same name then it should be OK.

I'll close this issue, I don't see any descriptions that contradict the assumption that it is working as intended.