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.
https://pub.dev/packages/reflectable
BSD 3-Clause "New" or "Revised" License
381 stars 57 forks source link

Transformer error without direct dependency #84

Closed stevenroose closed 8 years ago

stevenroose commented 8 years ago

I have a project in which I use a library that uses reflectable. I get this error:

EXCEPTION: Bad state: Reflectable has not been initialized. Did you forget to add the main file to the reflectable transformer's entry_points in pubspec.yaml?

Is this an error in the library that is using reflectable? Or do all packages that have an indirect dependency on reflectable also depend directly on it?

I can't just add the transformer to the pubspec.yaml file either because the package is not a direct dependency.

jakemac53 commented 8 years ago

You must include the reflectable transformer in your package, it always lives in the application package not the libraries (it operates on the entry point of the app).

stevenroose commented 8 years ago

@jakemac53 It's not mentioned under known limitations or anywhere else in the README.

Just saying, reflection is not normally something web application packages use, but more something the libraries they use use...

jakemac53 commented 8 years ago

While you might not have a direct import to reflectable, your code is almost certainly using it indirectly. The way reflectable works it needs to operate on the entire app in order to generate exactly the code that is needed based on the reflection capabilites that were requested.

eernstg commented 8 years ago

Thanks, Jacob, for resolving this!

I'd add just one extra remark for clarification: When an application package A depends on a package B which uses Reflectable, the typical situation is actually that B needs to use reflection because it abstracts over declared entities in a way that is more general than the built-in mechanisms allow. For instance, it may give access to knowledge about all subtypes of a given class (say, JsProxy) and their declarations or a specified subset thereof. Reflectable needs to support this scenario via (normal, non-reflective) code generated at compile-time, so the reflectable transformer has to look at package A in order to generate support for reflection on things declared there.

Because of this, it is typically not true that "only B uses reflectable", reflectable really needs to run on the whole program in order to enable B to do its job.

stevenroose commented 8 years ago

I understand why it is required. I don't understand why it is not documented. It's not straightforward for a beginning Dart developer what to do with that error if they have never heard of the reflectable package.

eernstg commented 8 years ago

Ah, you're right, I did not see it from that angle. I added a paragraph to README.md about it, so it will be included with the next version of reflectable.

eernstg commented 8 years ago

Change performed in https://codereview.chromium.org/2002033002/, landed in b3f302ba3249f14177ad7b26d26d75915aab6980.

stevenroose commented 8 years ago

Thanks @eernstg!