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

`Parcelable` not allowed as `@Extra`? #159

Closed justincpollard closed 9 years ago

justincpollard commented 9 years ago

Hi John,

Is Parcelable allowed as an @Extra annotated constructor parameter in a Transfuse activity? It appears that code generation won't complete when I do so. For example:

/**
 * Created by justinpollard on 4/9/15.
 */
@Activity
@Layout(R.layout.a_gallery)
@RegisterListener
public class SomeActivity {

  private final Parcelable myParcelable;

  @Inject
  public SomeActivity(@Extra(value = "myParcelable", optional = true) Parcelable myParcelable) {
    this.myParcelable = myParcelable;
  }

}

This appears to throw the following exception:

Exception in thread "pool-919-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)
    at org.androidtransfuse.guava.collect.Iterators$8.transform(Iterators.java:794)
    at org.androidtransfuse.guava.collect.TransformedIterator.next(TransformedIterator.java:48)
    at org.androidtransfuse.guava.collect.ImmutableList.copyOf(ImmutableList.java:271)
    at org.androidtransfuse.guava.collect.ImmutableList.copyOf(ImmutableList.java:226)
    at org.androidtransfuse.guava.collect.FluentIterable.toList(FluentIterable.java:334)
    at org.androidtransfuse.gen.ExpressionMatchingListFactory.build(ExpressionMatchingListFactory.java:47)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:109)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:101)
    at org.androidtransfuse.gen.ExceptionWrapper.wrapException(ExceptionWrapper.java:45)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder.buildVariable(VariableInjectionBuilder.java:99)
    at org.androidtransfuse.gen.variableDecorator.VariableBuilderExpressionDecorator.buildVariableExpression(VariableBuilderExpressionDecorator.java:31)
    at org.androidtransfuse.gen.variableDecorator.VirtualProxyExpressionDecorator.buildVariableExpression(VirtualProxyExpressionDecorator.java:66)
    at org.androidtransfuse.gen.variableDecorator.ScopedExpressionDecorator.buildVariableExpression(ScopedExpressionDecorator.java:42)
    at org.androidtransfuse.gen.variableDecorator.CachedExpressionDecorator.buildVariableExpression(CachedExpressionDecorator.java:40)
    at org.androidtransfuse.gen.InjectionExpressionBuilder.buildVariable(InjectionExpressionBuilder.java:35)
    at org.androidtransfuse.gen.InjectionFragmentGenerator.buildFragment(InjectionFragmentGenerator.java:57)
    at org.androidtransfuse.experiment.generators.OnCreateInjectionGenerator$1.generate(OnCreateInjectionGenerator.java:85)
    at org.androidtransfuse.experiment.ComponentBuilder$MethodMetaData.build(ComponentBuilder.java:64)
    at org.androidtransfuse.experiment.ComponentBuilder.build(ComponentBuilder.java:120)
    at org.androidtransfuse.experiment.ComponentGenerator.build(ComponentGenerator.java:46)
johncarl81 commented 9 years ago

Hmm, it should be allowed... I'll investigate.

johncarl81 commented 9 years ago

It seems that the annotation processor represents an empty extension (Parcelable is an interface and doesn't extend another interface) as the NoType. Tinkering with this a bit, it seems that if we substitute an Object ASTType we can successfully cast the return type of Object getExtras() as a Parcelable because the check that ensure we can cast succeeds (that's what was failing in the stack trace above).

I've done a bit of testing around this, but Im a bit hesitant to make this substitution. You'll find this update on 0.3.0-SNAPSHOT or on the object_notype branch. I'd appreciate a second pair of eyes, a test and feedback.

johncarl81 commented 9 years ago

@justincpollard Ping.

justincpollard commented 9 years ago

Hey @johncarl81, sorry I've been pretty busy over the past couple days. I'll try to take a look tonight or tomorrow! I think the best I'll be able to do is test the snapshot; I'm not very familiar with working with the annotation processor, but I'll take a look regardless.

johncarl81 commented 9 years ago

Cool, just eager to see this fix work!

justincpollard commented 9 years ago

Hey John,

Please forgive my naivety, but how do I get the 0.3.0-SNAPSHOT? Is it on Maven Central? Do I need to build the jar myself?

johncarl81 commented 9 years ago

Yes, it's on the Maven Central SNAPSHOT repo: https://oss.sonatype.org/content/repositories/snapshots/org/androidtransfuse/transfuse/0.3.0-SNAPSHOT/ So, to get it, it depends on your build. Are you using gradle or Maven?

justincpollard commented 9 years ago

@johncarl81 I'm using gradle

johncarl81 commented 9 years ago

Gradle makes it easy, just add this repository:

repositories {
    mavenCentral()
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots/"
    }
}

and, of course, update the Transfuse dependency:

    apt 'org.androidtransfuse:transfuse:0.3.0-SNAPSHOT'
    compile 'org.androidtransfuse:transfuse-api:0.3.0-SNAPSHOT'

Here's a working example: https://github.com/johncarl81/transfuse/tree/master/examples/gradle

justincpollard commented 9 years ago

Hi John,

Sorry to take so long to get back to you. Unfortunately, it doesn't look like the latest code on 0.3.0-SNAPSHOT fixed the problem. After adding an @Extra Parcelable your example gradle project GradleTransfuse, building the project errors out with essentially the same exception:

Exception in thread "pool-7-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)
    at com.google.common.collect.Iterators$8.transform(Iterators.java:794)
    at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:271)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:226)
    at com.google.common.collect.FluentIterable.toList(FluentIterable.java:334)
    at org.androidtransfuse.gen.ExpressionMatchingListFactory.build(ExpressionMatchingListFactory.java:47)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:109)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:101)
    at org.androidtransfuse.gen.ExceptionWrapper.wrapException(ExceptionWrapper.java:45)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder.buildVariable(VariableInjectionBuilder.java:99)
    at org.androidtransfuse.gen.variableDecorator.VariableBuilderExpressionDecorator.buildVariableExpression(VariableBuilderExpressionDecorator.java:31)
    at org.androidtransfuse.gen.variableDecorator.VirtualProxyExpressionDecorator.buildVariableExpression(VirtualProxyExpressionDecorator.java:66)
    at org.androidtransfuse.gen.variableDecorator.ScopedExpressionDecorator.buildVariableExpression(ScopedExpressionDecorator.java:42)
    at org.androidtransfuse.gen.variableDecorator.CachedExpressionDecorator.buildVariableExpression(CachedExpressionDecorator.java:40)
    at org.androidtransfuse.gen.InjectionExpressionBuilder.buildVariable(InjectionExpressionBuilder.java:35)
    at org.androidtransfuse.gen.InjectionFragmentGenerator.buildFragment(InjectionFragmentGenerator.java:57)
    at org.androidtransfuse.experiment.generators.OnCreateInjectionGenerator$1.generate(OnCreateInjectionGenerator.java:79)
    at org.androidtransfuse.experiment.ComponentBuilder$MethodMetaData.build(ComponentBuilder.java:64)
    at org.androidtransfuse.experiment.ComponentBuilder.build(ComponentBuilder.java:120)
    at org.androidtransfuse.experiment.ComponentGenerator.build(ComponentGenerator.java:46)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:47)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:29)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
    at org.androidtransfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
    at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
    at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Exception in thread "pool-15-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)
    at com.google.common.collect.Iterators$8.transform(Iterators.java:794)
    at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:271)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:226)
    at com.google.common.collect.FluentIterable.toList(FluentIterable.java:334)
    at org.androidtransfuse.gen.ExpressionMatchingListFactory.build(ExpressionMatchingListFactory.java:47)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:109)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:101)
    at org.androidtransfuse.gen.ExceptionWrapper.wrapException(ExceptionWrapper.java:45)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder.buildVariable(VariableInjectionBuilder.java:99)
    at org.androidtransfuse.gen.variableDecorator.VariableBuilderExpressionDecorator.buildVariableExpression(VariableBuilderExpressionDecorator.java:31)
    at org.androidtransfuse.gen.variableDecorator.VirtualProxyExpressionDecorator.buildVariableExpression(VirtualProxyExpressionDecorator.java:66)
    at org.androidtransfuse.gen.variableDecorator.ScopedExpressionDecorator.buildVariableExpression(ScopedExpressionDecorator.java:42)
    at org.androidtransfuse.gen.variableDecorator.CachedExpressionDecorator.buildVariableExpression(CachedExpressionDecorator.java:40)
    at org.androidtransfuse.gen.InjectionExpressionBuilder.buildVariable(InjectionExpressionBuilder.java:35)
    at org.androidtransfuse.gen.InjectionFragmentGenerator.buildFragment(InjectionFragmentGenerator.java:57)
    at org.androidtransfuse.experiment.generators.OnCreateInjectionGenerator$1.generate(OnCreateInjectionGenerator.java:79)
    at org.androidtransfuse.experiment.ComponentBuilder$MethodMetaData.build(ComponentBuilder.java:64)
    at org.androidtransfuse.experiment.ComponentBuilder.build(ComponentBuilder.java:120)
    at org.androidtransfuse.experiment.ComponentGenerator.build(ComponentGenerator.java:46)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:47)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:29)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
    at org.androidtransfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
:GradleTransfuse:compileDebugJava FAILED
    at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
    at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':GradleTransfuse:compileDebugJava'.
> org.androidtransfuse.TransfuseAnalysisException: Code generation did not complete successfully.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 5.444 secs
johncarl81 commented 9 years ago

Shoot, I think logistics go the better of this situation, I think I deployed something old to SNAPSHOT... I just redeployed, can you test again, possibly refreshing dependencies (./gradlew clean build --refresh dependencies)?

justincpollard commented 9 years ago

Similar outcome, I'm afraid:

Exception in thread "pool-6-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)
    at com.google.common.collect.Iterators$8.transform(Iterators.java:794)
    at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:271)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:226)
    at com.google.common.collect.FluentIterable.toList(FluentIterable.java:334)
    at org.androidtransfuse.gen.ExpressionMatchingListFactory.build(ExpressionMatchingListFactory.java:47)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:109)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:101)
    at org.androidtransfuse.gen.ExceptionWrapper.wrapException(ExceptionWrapper.java:45)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder.buildVariable(VariableInjectionBuilder.java:99)
    at org.androidtransfuse.gen.variableDecorator.VariableBuilderExpressionDecorator.buildVariableExpression(VariableBuilderExpressionDecorator.java:31)
    at org.androidtransfuse.gen.variableDecorator.VirtualProxyExpressionDecorator.buildVariableExpression(VirtualProxyExpressionDecorator.java:66)
    at org.androidtransfuse.gen.variableDecorator.ScopedExpressionDecorator.buildVariableExpression(ScopedExpressionDecorator.java:42)
    at org.androidtransfuse.gen.variableDecorator.CachedExpressionDecorator.buildVariableExpression(CachedExpressionDecorator.java:40)
    at org.androidtransfuse.gen.InjectionExpressionBuilder.buildVariable(InjectionExpressionBuilder.java:35)
    at org.androidtransfuse.gen.InjectionFragmentGenerator.buildFragment(InjectionFragmentGenerator.java:57)
    at org.androidtransfuse.experiment.generators.OnCreateInjectionGenerator$1.generate(OnCreateInjectionGenerator.java:79)
    at org.androidtransfuse.experiment.ComponentBuilder$MethodMetaData.build(ComponentBuilder.java:64)
    at org.androidtransfuse.experiment.ComponentBuilder.build(ComponentBuilder.java:120)
    at org.androidtransfuse.experiment.ComponentGenerator.build(ComponentGenerator.java:46)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:47)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:29)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
    at org.androidtransfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
    at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
    at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Exception in thread "pool-14-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)
    at com.google.common.collect.Iterators$8.transform(Iterators.java:794)
    at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:271)
    at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:226)
    at com.google.common.collect.FluentIterable.toList(FluentIterable.java:334)
    at org.androidtransfuse.gen.ExpressionMatchingListFactory.build(ExpressionMatchingListFactory.java:47)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:109)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder$1.write(VariableInjectionBuilder.java:101)
    at org.androidtransfuse.gen.ExceptionWrapper.wrapException(ExceptionWrapper.java:45)
    at org.androidtransfuse.gen.variableBuilder.VariableInjectionBuilder.buildVariable(VariableInjectionBuilder.java:99)
    at org.androidtransfuse.gen.variableDecorator.VariableBuilderExpressionDecorator.buildVariableExpression(VariableBuilderExpressionDecorator.java:31)
:GradleTransfuse:compileDebugJava FAILED
    at org.androidtransfuse.gen.variableDecorator.VirtualProxyExpressionDecorator.buildVariableExpression(VirtualProxyExpressionDecorator.java:66)
    at org.androidtransfuse.gen.variableDecorator.ScopedExpressionDecorator.buildVariableExpression(ScopedExpressionDecorator.java:42)
    at org.androidtransfuse.gen.variableDecorator.CachedExpressionDecorator.buildVariableExpression(CachedExpressionDecorator.java:40)
    at org.androidtransfuse.gen.InjectionExpressionBuilder.buildVariable(InjectionExpressionBuilder.java:35)
    at org.androidtransfuse.gen.InjectionFragmentGenerator.buildFragment(InjectionFragmentGenerator.java:57)
    at org.androidtransfuse.experiment.generators.OnCreateInjectionGenerator$1.generate(OnCreateInjectionGenerator.java:79)
    at org.androidtransfuse.experiment.ComponentBuilder$MethodMetaData.build(ComponentBuilder.java:64)
    at org.androidtransfuse.experiment.ComponentBuilder.build(ComponentBuilder.java:120)
    at org.androidtransfuse.experiment.ComponentGenerator.build(ComponentGenerator.java:46)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:47)
    at org.androidtransfuse.gen.AnalysisGeneration.innerRun(AnalysisGeneration.java:29)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
    at org.androidtransfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
    at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
    at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
    at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
johncarl81 commented 9 years ago

Hmm, shoot, Im able to test the SomeActivity class you provided with success. It even generates the proper Strategy builder class. Would you mind pinging me on Google Hangouts?

johncarl81 commented 9 years ago

Alright, I think we solved this, so I'm closing, feel free to reopen if this is still a problem.