johncarl81 / transfuse

:syringe: Transfuse - A Dependency Injection and Integration framework for Google Android
http://androidtransfuse.org/
Apache License 2.0
220 stars 28 forks source link

Non-coercible type in undisclosed location. #154

Closed dbachelder closed 9 years ago

dbachelder commented 9 years ago

But where?!

Exception in thread "pool-8-thread-1" org.androidtransfuse.TransfuseAnalysisException: Non-coercible types encountered
    at org.androidtransfuse.gen.invocationBuilder.TypeInvocationHelper.coerceType(TypeInvocationHelper.java:75)
    at org.androidtransfuse.gen.invocationBuilder.TypeInvocationHelper.getExpression(TypeInvocationHelper.java:49)
    at org.androidtransfuse.gen.ExpressionMatchingListFactory$1.apply(ExpressionMatchingListFactory.java:45)
    at org.androidtransfuse.gen.ExpressionMatchingListFactory$1.apply(ExpressionMatchingListFactory.java:43)
dbachelder commented 9 years ago

Found it.... I forgot I had added an extra injection...

@Extra(value="requestedDocs", optional = true) List<String> docs

Clearly that needs to be ArrayList... but man.. when you have a bunch of changes and the build just blows up on you... not fun.

Can we leave this open as a heads up to make this error more descriptive?

johncarl81 commented 9 years ago

Ugh, my apologies. This is certainly a rough spot of Transfuse. Annotation processing does have nice facilities for this sort of error as well, including line number and what element caused the issue.

Yes, lets leave this open. This needs to be a priority for the next release.

johncarl81 commented 9 years ago

@dbachelder, I used a, imo, successful approach with Parceler to test the various success and error cases around code analysis and generation. You can see the tests here: https://github.com/johncarl81/parceler/blob/master/parceler/src/test/java/org/parceler/internal/ParcelableAnalysisTest.java This ensures that we cover all the corner cases and helps weed out these sorts of cases. What do you think about pursuing an approach like this with Transfuse? The big question is how do we accomplish this? Could we test each injection type in isolation?

dbachelder commented 9 years ago

This seems reasonable to me! I am certainly not familiar with testing this sort of code... So I'm afraid I don't have too many thoughts on the matter.

johncarl81 commented 9 years ago

A quick update, the core of this issue will be fixed with the results of #159. Something else came to mind though, we could probably support a wider varieity of Extras in a better way. Currently ArrayList works because it's serializable... not the best way to pass parameters between Contexts with Parceler in the mix. Parceler fully supports ArrayList and List and a ton of other types and collections. The only problem is that we need to tell Transfuse to use Parceler even when the given type isn't annotated. Im thinking that we could add a parameter to the @Extra to force Transfuse to wrap/unwrap with Parceler, something like this: @Extra(forceParcelerWrap=true) List<SomeType> list; Thoughts?

johncarl81 commented 9 years ago

Ok, made some more progress on this... what do you think about these errors:

Gradle:

:GradleTransfuse:compileDebug
/.../Main.java:33: error: Transfuse: @Extra type java.util.List not available for marshalling.
        public List<String> values;
                            ^

Maven:

[ERROR] /.../ExtraInjection.java:[47,26] Transfuse: @Extra type java.util.List not available for marshalling.
dbachelder commented 9 years ago

Yes!! +1000

johncarl81 commented 9 years ago

Ok, I went ahead and added the forceParceler parameter to @Extra as well, so you can now use classes generated by @ParcelClass as well as Parceler's collection support. In short this should work now:

@Extra(value="requestedDocs", optional = true, forceParceler = true) List<String> docs
johncarl81 commented 9 years ago

Ok, after thinking about this over the weekend I've decided to also make Transfuse (and Parceler) avoid throwing exceptions directly, and instead just logging errors. This allows the regular compilation cycle to show its errors instead of Transfuse getting in the way with an ugly stacktrace. For instance. if you add a field that doesn't compile in an @Activity then the resulting error would be: Maven:

[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /mnt/hd1/home/john/dev/transfuse-project/examples/integrationTest/src/main/java/org/androidtransfuse/integrationTest/IntegrationApp.java:[31,13] cannot find symbol
  symbol:   class DontCompile
  location: class org.androidtransfuse.integrationTest.IntegrationApp
[ERROR] Transfuse: Code generation did not complete successfully.  For more details add the compiler argument transfuseStacktrace=true
[INFO] 2 errors 
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.484s
[INFO] Finished at: Mon Apr 20 19:20:18 MDT 2015
[INFO] Final Memory: 54M/627M

Gradle:

$ ./gradlew clean build
:GradleTransfuse:clean
:GradleTransfuse:preBuild UP-TO-DATE
:GradleTransfuse:preDebugBuild UP-TO-DATE
:GradleTransfuse:compileDebugNdk UP-TO-DATE
:GradleTransfuse:checkDebugManifest
:GradleTransfuse:prepareDebugDependencies
:GradleTransfuse:compileDebugAidl
:GradleTransfuse:compileDebugRenderscript
:GradleTransfuse:generateDebugBuildConfig
:GradleTransfuse:generateDebugAssets UP-TO-DATE
:GradleTransfuse:mergeDebugAssets
:GradleTransfuse:generateDebugResValues
:GradleTransfuse:generateDebugResources
:GradleTransfuse:mergeDebugResources
:GradleTransfuse:processDebugManifest
:GradleTransfuse:processDebugResources
:GradleTransfuse:generateDebugSources
:GradleTransfuse:compileDebugJava
/mnt/hd1/home/john/dev/transfuse-project/examples/gradle/GradleTransfuse/src/main/java/org/gradletransfuse/Main.java:27: error: cannot find symbol
        private DontCompile dontCompile;
                ^
  symbol:   class DontCompile
  location: class Main
error: Transfuse: Code generation did not complete successfully.  For more details add the compiler argument transfuseStacktrace=true
Note: Transfuse: Took 46ms to process
2 errors
:GradleTransfuse:compileDebugJava FAILED
johncarl81 commented 9 years ago

The last bit of this effort is to add pervasive debug logging.

dbachelder commented 9 years ago

I'd like to increase my previous vote by a factor of 10

johncarl81 commented 9 years ago

LOL +10,000! You know what that does...

super_sayian

johncarl81 commented 9 years ago

This validation issue should be solved with 0.3.0-beta-5. There will be more spots to touch up though. OK to Close?

dbachelder commented 9 years ago

:+1: