-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incremental compilation support seems implemented incorrectly to me #24
Comments
Hi! Thanks for creating this issue. First of all, we decided to ditch MoxyReflector in favor of actual reflection, as Class.forName() is as fast, as using generated code. This will take away the burden of declaring @RegisterMoxyReflectorPackages and moxyReflectorPackage option for users. Also we tried to split processor into aggregating and isolating, but this idea was rejected. You cannot declare originating element in ViewStateClassGenerator, as it breaks rules for isolating processors(no annotations in View interfaces). I think declaring originatingElement takes no effect in aggregating processors, but this supposition have to be checked. I think i will go through your original PR to cherry-pick some changes, if you don't mind. |
I didn't hear about that. Based on gradle incremental annotation processing documentation isolating processors have following limitations:
Where did you find this info? Anyway, If you are going to remove
Hmm, actually I don't know if this is true. Gradle documentation says nothing about originating elements in aggregating processor, so it can be true.
Sure, I wanted to do it by myself, but broken tests really makes me feel uncomfortable because I can break something. |
Based on this item:
ViewStates are generated for View interfaces, that are type parameters of MvpPresenters, or parameters of @InjectPresenter annotation. This is what contradicts referenced item - MvpPresenter is unrelated for View interface. If you change View interface, isolating annotation processor won't be able to restart processing to generate ViewState, cause there's no annotation on interface. |
Sorry, I'm still can't get it. So if we ignore Lets say we have following classes: class ExampleFragment : ExampleView {
@InjectPresenter
lateinit var presenter: ExamplePresenter
}
class ExampleView: MvpView {
@StateStrategyType(AddToEndSingleStateStrategy::class)
fun showNumber(number: Long)
}
@InjectViewState
class ExamplePresenter : MvpPresenter<ExampleView> {
}
I think I missing something important but can't figure out what? |
What does this mean? Can we somehow use @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectPresenter {
String EMPTY = "";
String tag() default EMPTY;
PresenterType type() default PresenterType.LOCAL;
String presenterId() default EMPTY;
} |
Oh, I think I get it. You are worry because we are not annotating view interface itself, right? I think this is ok because view interface is part of presenter AST, which means if we change it, this will trigger |
Yes, but what would you set as originating element for generated ViewState? I've tested all of the above, when i tried to make it isolating, and gradle consistently failed. |
Hmm, this is strange because it worked fine for me. Probably my tests was incorrect, I'll try again more carefully. |
Can you please tell me how did you test this? I'm not able to reproduce this behavior. What I'm trying is:
interface MainView : MvpView {
fun printLog(msg: String)
fun showNumber(i: Long) // this method
}
package example.com.moxy_androidx_sapmle;
import com.arellomobile.mvp.viewstate.MvpViewState;
import com.arellomobile.mvp.viewstate.ViewCommand;
import com.arellomobile.mvp.viewstate.strategy.AddToEndStrategy;
import java.lang.Override;
import java.lang.String;
public class MainView$$State extends MvpViewState<MainView> implements MainView {
@Override
public void printLog(String msg) {
PrintLogCommand printLogCommand = new PrintLogCommand(msg);
mViewCommands.beforeApply(printLogCommand);
if (mViews == null || mViews.isEmpty()) {
return;
}
for (MainView view : mViews) {
view.printLog(msg);
}
mViewCommands.afterApply(printLogCommand);
}
@Override
public void showNumber(long i) {
ShowNumberCommand showNumberCommand = new ShowNumberCommand(i);
mViewCommands.beforeApply(showNumberCommand);
if (mViews == null || mViews.isEmpty()) {
return;
}
for (MainView view : mViews) {
view.showNumber(i);
}
mViewCommands.afterApply(showNumberCommand);
}
public class PrintLogCommand extends ViewCommand<MainView> {
public final String msg;
PrintLogCommand(String msg) {
super("printLog", AddToEndStrategy.class);
this.msg = msg;
}
@Override
public void apply(MainView mvpView) {
mvpView.printLog(msg);
}
}
public class ShowNumberCommand extends ViewCommand<MainView> {
public final long i;
ShowNumberCommand(long i) {
super("showNumber", AddToEndStrategy.class);
this.i = i;
}
@Override
public void apply(MainView mvpView) {
mvpView.showNumber(i);
}
}
} Build logs: info.txt Am I missing something? |
Gradle supports IntAP starting from 4.7, your project is built with gradle 4.6 Also i've run some tests, seems like change in MainView triggers MainPresenter invalidation, which in turn triggers annotation processing on MainPresenter, which causes MainView$$State to be generated again. It`s kinda strange, but i will take a closer look at it. |
Damn, how can I forgot about it 😞 Anyway, I updated dependencies and everything still works.
That what I'm saying! Let's consider this item again:
What this mean is changing view interface should trigger annotation processing on presenter because processor can make decisions about generated code based on information from view interface accessed transitively. And this is what triggers |
For proper support of incremental compilation you should provide originating elements when creating source files. See
Filer#createSourceFile(CharSequence, Element...)
documentation. When usingJavaPoet
you should specify originating elements usingTypeSpec.Builder#addOriginatingElement(Element)
method. I can't spot a single call to this method in this repo, which can lead to missing files during build, some generated files not being rebuild when needed and other problems.Another problem I spot is you declare your annotation processor both using
AutoService
library andMETA-INF.services
file, which is kinda strange becauseAutoService
is generating this file for you.Also you can optimize incap support by splitting
MvpCompiler
into two - one for generatingMoxyReflector
(this one is aggregating) and one for other stuff (isolating).I did so in my PR with incap support to original repo. I can work on migrating my changes into this repo, but I don't want to do so while processor tests are broken. I created another issue about it - #23.
The text was updated successfully, but these errors were encountered: