diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..d354de5 --- /dev/null +++ b/BUILD.md @@ -0,0 +1,6 @@ +# Build steps: + +1. Add build info to `CHANGELOG.md` +2. Update version name in `gradle.properties` and `plugin/src/main/groovy/BladePlugin.groovy` +3. Clean & build the project `./gradlew clean install` +4. Upload to Bintray `./gradlew bintrayUpload` diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bff307..e8b816d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log ========== +Version 2.6.4 *(2017-10-16)* +---------------------------- + + * Fix: Superclass Presenter injection. + * New: Add more unit tests. + Version 2.6.3 *(2017-04-16)* ---------------------------- diff --git a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/arg/ArgHelperSpecification.groovy b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/arg/ArgHelperSpecification.groovy index 0843ec8..deb4c9f 100644 --- a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/arg/ArgHelperSpecification.groovy +++ b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/arg/ArgHelperSpecification.groovy @@ -14,7 +14,7 @@ import eu.f3rog.blade.core.Weave import spock.lang.Unroll import javax.tools.JavaFileObject -import javax.tools.StandardLocation + public final class ArgHelperSpecification extends BaseSpecification { diff --git a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/combination/CombinedSpecification.groovy b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/combination/CombinedSpecification.groovy index 4723a4b..152047e 100644 --- a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/combination/CombinedSpecification.groovy +++ b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/combination/CombinedSpecification.groovy @@ -4,8 +4,10 @@ import android.app.Activity import android.app.Fragment import android.content.Intent import android.os.Bundle +import android.os.Parcelable import blade.Arg import blade.Extra +import blade.Parcel import blade.State import blade.mvp.BasePresenter import blade.mvp.IView @@ -25,7 +27,7 @@ public final class CombinedSpecification extends BaseSpecification { @Unroll - def "generate _Helper for a Fragment class with a @Arg+@State field (#annotations)"() { + def "generate _Helper for a Fragment class with #annotations"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyFragment", """ @@ -110,7 +112,7 @@ public final class CombinedSpecification } @Unroll - def "generate _Helper for an Activity class with a @Extra+@State field (#annotations)"() { + def "generate _Helper for an Activity class with #annotations"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -409,4 +411,111 @@ public final class CombinedSpecification '@#S boolean mFlag;' | '@#E String mTitle;' | '@#I #P mPresenter;' | _ '@#S boolean mFlag;' | '@#I #P mPresenter;' | '@#E String mTitle;' | _ } + + def "generate _Helper for a class with @Parcel + @State"() { + given: + final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", + """ + @#P + public class #T implements Parcelable { + + @#S + int number; + + public #T(android.os.Parcel p) { + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(android.os.Parcel dest, int flags) { + } + } + """, + [ + P: Parcel.class, + S: State.class, + _: [Parcelable.class] + ] + ) + + expect: + final JavaFileObject expected = JavaFile.newGeneratedFile("com.example", "MyActivity_Helper", + """ + abstract class #T { + + @Weave( + into = "", + statement = "com.example.#T.CREATOR" + ) + public static final Parcelable.Creator<#I> CREATOR = + new Parcelable.Creator<#I>() { + @Override + public #I createFromParcel(Parcel in) { + return new #I(in); + } + @Override + public #I[] newArray(int size) { + return new #I[size]; + } + }; + + @Weave( + into = "0>writeToParcel", + args = {"android.os.Parcel", "int"}, + statement = "com.example.#T.writeToParcel(this, \$1);" + ) + public static void writeToParcel(#I target, Parcel parcel) { + parcel.writeInt(target.number); + } + + @Weave( + into = "", + args = {"android.os.Parcel"}, + statement = "com.example.#T.readFromParcel(this, \$1);" + ) + public static void readFromParcel(#I target, Parcel parcel) { + target.number = parcel.readInt(); + } + + public static void saveState(#I target, Bundle state) { + if (state == null) { + throw new #E("State cannot be null!"); + } + BundleWrapper bundleWrapper = BundleWrapper.from(state); + bundleWrapper.put("", target.number); + } + + public static void restoreState(#I target, Bundle state) { + if (state == null) { + return; + } + BundleWrapper bundleWrapper = BundleWrapper.from(state); + target.number = bundleWrapper.get("", target.number); + } + } + """, + [ + I: input, + E: IllegalArgumentException.class, + _: [ + android.os.Parcel.class, + Parcelable.class, + Override.class, + Bundle.class, + BundleWrapper.class, + Weave.class + ] + ] + ) + + assertFiles(input) + .with(BladeProcessor.Module.PARCEL, BladeProcessor.Module.STATE) + .compilesWithoutError() + .and() + .generatesSources(expected) + } } \ No newline at end of file diff --git a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/ExtraHelperSpecification.groovy b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/ExtraHelperSpecification.groovy index 261388e..5665679 100644 --- a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/ExtraHelperSpecification.groovy +++ b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/ExtraHelperSpecification.groovy @@ -7,23 +7,22 @@ import android.content.Intent import android.os.Bundle import android.os.IBinder import blade.Blade +import blade.Bundler import blade.Extra import eu.f3rog.blade.compiler.BaseSpecification import eu.f3rog.blade.compiler.BladeProcessor import eu.f3rog.blade.compiler.ErrorMsg import eu.f3rog.blade.compiler.util.JavaFile import eu.f3rog.blade.core.BundleWrapper -import blade.Bundler import eu.f3rog.blade.core.Weave import spock.lang.Unroll import javax.tools.JavaFileObject -import javax.tools.StandardLocation public final class ExtraHelperSpecification extends BaseSpecification { - def "fail if @ is in invalid class"() { + def "fail if @Extra is in invalid class"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyClass", """ @@ -45,7 +44,7 @@ public final class ExtraHelperSpecification } @Unroll - def "fail if @ is on #accessor field"() { + def "fail if @Extra is on #accessor field"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -73,7 +72,7 @@ public final class ExtraHelperSpecification 'final' | _ } - def "do NOT generate _Helper if an Activity has only @Blade"() { + def "do NOT generate _Helper if an Activity class has only @Blade"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -87,18 +86,68 @@ public final class ExtraHelperSpecification ) expect: - try { - assertFiles(input) - .with(BladeProcessor.Module.EXTRA) - .compilesWithoutError() - .and() - .generatesFileNamed(StandardLocation.CLASS_OUTPUT, "com.example", "MyActivity_Helper.class") - } catch (AssertionError e) { - assert e.getMessage().contains("Did not find a generated file corresponding to MyActivity_Helper.class in package com.example") - } + compilesWithoutErrorAndDoesntGenerate("com.example", "MyActivity_Helper", BladeProcessor.Module.EXTRA, input) + } + + @Unroll + def "generate _Helper if 1 @Extra #type is in an Activity class"() { + given: + final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", + """ + public class #T extends Activity { + + @#E $type mFlag; + } + """, + [ + E: Extra.class, + _: [Activity.class] + ] + ) + + expect: + final JavaFileObject expected = JavaFile.newGeneratedFile("com.example", "MyActivity_Helper", + """ + abstract class #T { + + @Weave( + into = "0^onCreate", + args = {"android.os.Bundle"}, + statement = "com.example.#T.inject(this);" + ) + public static void inject(#I target) { + Intent intent = target.getIntent(); + if (intent == null || intent.getExtras() == null) { + return; + } + BundleWrapper extras = BundleWrapper.from(intent.getExtras()); + target.mFlag = extras.get("", target.mFlag); + } + } + """, + [ + I: input, + _: [BundleWrapper.class, Intent.class, Weave.class] + ] + ) + + assertFiles(input) + .with(BladeProcessor.Module.EXTRA) + .compilesWithoutError() + .and() + .generatesSources(expected) + + where: + type | _ + 'byte' | _ + 'boolean' | _ + 'int' | _ + 'float' | _ + 'double' | _ + 'String' | _ } - def "generate _Helper if 2 @ are in an Activity"() { + def "generate _Helper if 2 @Extra are in an Activity class"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -148,7 +197,7 @@ public final class ExtraHelperSpecification .generatesSources(expected) } - def "generate _Helper if 2 @ are in an Activity - 1 custom Bundler"() { + def "generate _Helper if 2 @Extra are in an Activity class - 1 custom Bundler"() { given: final JavaFileObject customBundler = JavaFile.newFile("com.example", "StringBundler", """ @@ -217,7 +266,7 @@ public final class ExtraHelperSpecification .generatesSources(expected) } - def "generate _Helper if 2 @ are in an Service"() { + def "generate _Helper if 2 @Extra are in a Service class"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyService", """ @@ -270,7 +319,7 @@ public final class ExtraHelperSpecification .generatesSources(expected) } - def "generate _Helper if 2 @ are in an IntentService"() { + def "generate _Helper if 2 @Extra are in an IntentService class"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyIntentService", """ @@ -327,7 +376,7 @@ public final class ExtraHelperSpecification .generatesSources(expected) } - def "generate _Helper for a generic Activity with 2 @Extra"() { + def "generate _Helper if 2 @Extra are in a generic Activity class"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -338,8 +387,8 @@ public final class ExtraHelperSpecification } """, [ - E : Extra.class, - _ : [Activity.class] + E: Extra.class, + _: [Activity.class] ] ) @@ -365,8 +414,8 @@ public final class ExtraHelperSpecification } """, [ - I : input, - _ : [BundleWrapper.class, Intent.class, Weave.class] + I: input, + _: [BundleWrapper.class, Intent.class, Weave.class] ] ) @@ -377,7 +426,7 @@ public final class ExtraHelperSpecification .generatesSources(expected) } - def "generate _Helper for a generic Activity field with 2 @Extra"() { + def "generate _Helper if 2 @Extra are in a generic Activity class where T extends Serializable"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -388,8 +437,8 @@ public final class ExtraHelperSpecification } """, [ - E : Extra.class, - _ : [Activity.class, Serializable.class] + E: Extra.class, + _: [Activity.class, Serializable.class] ] ) @@ -415,8 +464,8 @@ public final class ExtraHelperSpecification } """, [ - I : input, - _ : [BundleWrapper.class, Intent.class, Serializable.class, Weave.class] + I: input, + _: [BundleWrapper.class, Intent.class, Serializable.class, Weave.class] ] ) @@ -427,7 +476,7 @@ public final class ExtraHelperSpecification .generatesSources(expected) } - def "generate _Helper for an inner Activity class"() { + def "generate _Helper if 2 @Extra are in an inner Activity class"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "Wrapper", """ @@ -441,8 +490,8 @@ public final class ExtraHelperSpecification } """, [ - E : Extra.class, - _ : [Activity.class] + E: Extra.class, + _: [Activity.class] ] ) @@ -468,8 +517,8 @@ public final class ExtraHelperSpecification } """, [ - I : input, - _ : [BundleWrapper.class, Intent.class, Weave.class] + I: input, + _: [BundleWrapper.class, Intent.class, Weave.class] ] ) @@ -480,7 +529,7 @@ public final class ExtraHelperSpecification .generatesSources(expected) } - def "generate _Helper for 2 inner Activity classes"() { + def "generate _Helper if 2 @Extra are in multiple inner Activity classes"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "Wrapper", """ @@ -500,8 +549,8 @@ public final class ExtraHelperSpecification } """, [ - E : Extra.class, - _ : [Activity.class] + E: Extra.class, + _: [Activity.class] ] ) @@ -527,8 +576,8 @@ public final class ExtraHelperSpecification } """, [ - I : input, - _ : [BundleWrapper.class, Intent.class, Weave.class] + I: input, + _: [BundleWrapper.class, Intent.class, Weave.class] ] ) final JavaFileObject expected2 = JavaFile.newGeneratedFile("com.example", "Wrapper_MyActivity2_Helper", @@ -552,8 +601,8 @@ public final class ExtraHelperSpecification } """, [ - I : input, - _ : [BundleWrapper.class, Intent.class, Weave.class] + I: input, + _: [BundleWrapper.class, Intent.class, Weave.class] ] ) diff --git a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/IntentBuilderSpecification.groovy b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/IntentBuilderSpecification.groovy index 5b13549..931102e 100644 --- a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/IntentBuilderSpecification.groovy +++ b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/extra/IntentBuilderSpecification.groovy @@ -5,19 +5,35 @@ import android.content.Context import android.content.Intent import android.os.Bundle import blade.Blade +import blade.Bundler import blade.Extra import eu.f3rog.blade.compiler.BaseSpecification import eu.f3rog.blade.compiler.BladeProcessor import eu.f3rog.blade.compiler.util.JavaFile import eu.f3rog.blade.core.BundleWrapper -import blade.Bundler import eu.f3rog.blade.core.GeneratedFor +import spock.lang.Unroll import javax.tools.JavaFileObject public final class IntentBuilderSpecification extends BaseSpecification { + def "do not generate if no Activity class need it"() { + given: + final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", + """ + public class #T extends Activity {} + """, + [ + _: [Activity.class] + ] + ) + + expect: + compilesWithoutErrorAndDoesntGenerate("blade", "I", BladeProcessor.Module.EXTRA, input) + } + def "generate for an Activity with only @Blade"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", @@ -66,13 +82,14 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate for an Activity with 1 @Extra"() { + @Unroll + def "generate for an Activity class with 1 @Extra #type"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ public class #T extends Activity { - @#E String mText; + @#E $type mField; } """, [ @@ -86,20 +103,77 @@ public final class IntentBuilderSpecification """ public class #T { - @#GF(#A.class) - public static Intent for#A(Context context, String mText) { - Intent intent = new Intent(context, #A.class); - #BW extras = new #BW(); - extras.put("", mText); - intent.putExtras(extras.getBundle()); - return intent; - } + @#GF(#A.class) + public static Intent for#A(Context context, $type mField) { + Intent intent = new Intent(context, #A.class); + #BW extras = new #BW(); + extras.put("", mField); + intent.putExtras(extras.getBundle()); + return intent; + } - @#GF(#A.class) - public static void start#A(Context context, String mText) { - context.startActivity(for#A(context, mText)); - } + @#GF(#A.class) + public static void start#A(Context context, $type mField) { + context.startActivity(for#A(context, mField)); + } + } + """, + [ + A : input, + BW: BundleWrapper.class, + GF: GeneratedFor.class, + _ : [Intent.class, Context.class] + ] + ) + + assertFiles(input) + .with(BladeProcessor.Module.EXTRA) + .compilesWithoutError() + .and() + .generatesSources(expected) + where: + type | _ + 'byte' | _ + 'boolean' | _ + 'int' | _ + 'float' | _ + 'double' | _ + } + + def "generate for an Activity class with 1 @Extra String"() { + given: + final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", + """ + public class #T extends Activity { + + @#E String mText; + } + """, + [ + E: Extra.class, + _: [Activity.class] + ] + ) + + expect: + final JavaFileObject expected = JavaFile.newGeneratedFile("blade", "I", + """ + public class #T { + + @#GF(#A.class) + public static Intent for#A(Context context, String mText) { + Intent intent = new Intent(context, #A.class); + #BW extras = new #BW(); + extras.put("", mText); + intent.putExtras(extras.getBundle()); + return intent; + } + + @#GF(#A.class) + public static void start#A(Context context, String mText) { + context.startActivity(for#A(context, mText)); + } } """, [ @@ -115,9 +189,17 @@ public final class IntentBuilderSpecification .compilesWithoutError() .and() .generatesSources(expected) + + where: + type | imp | _ + 'byte' | "" | _ + 'boolean' | "" | _ + 'int' | "" | _ + 'float' | "" | _ + 'double' | "" | _ } - def "generate for 2 Activities with @Extra"() { + def "generate for 2 Activity classes with @Extra"() { given: final JavaFileObject input1 = JavaFile.newFile("com.example", "FirstActivity", """ @@ -197,7 +279,7 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate for 2 Activities with inherited @Extra"() { + def "generate for 2 Activity classes with inherited @Extra"() { given: final JavaFileObject input1 = JavaFile.newFile("com.example", "BaseActivity", """ @@ -274,7 +356,7 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate for 1 Activity with inherited @Extra from abstract class"() { + def "generate for 1 Activity class with inherited @Extra from an abstract class"() { given: final JavaFileObject input1 = JavaFile.newFile("com.example", "BaseActivity", """ @@ -336,7 +418,7 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate for an Activity with @Extra and custom Bundler"() { + def "generate for an Activity class with @Extra and custom Bundler"() { given: final JavaFileObject customBundler = JavaFile.newFile("com.example", "StringBundler", """ @@ -412,7 +494,7 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate for a generic Activity with 2 @Extra"() { + def "generate for a generic Activity class with 2 @Extra"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -423,8 +505,8 @@ public final class IntentBuilderSpecification } """, [ - E : Extra.class, - _ : [Activity.class] + E: Extra.class, + _: [Activity.class] ] ) @@ -464,7 +546,7 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate _Helper for a generic Activity field with 2 @Extra"() { + def "generate for a generic Activity class with 2 @Extra"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -475,8 +557,8 @@ public final class IntentBuilderSpecification } """, [ - E : Extra.class, - _ : [Activity.class, Serializable.class] + E: Extra.class, + _: [Activity.class, Serializable.class] ] ) @@ -516,7 +598,7 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate _Helper for an inner Activity class"() { + def "generate for an inner Activity class"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "Wrapper", """ @@ -530,8 +612,8 @@ public final class IntentBuilderSpecification } """, [ - E : Extra.class, - _ : [Activity.class] + E: Extra.class, + _: [Activity.class] ] ) @@ -571,7 +653,7 @@ public final class IntentBuilderSpecification .generatesSources(expected) } - def "generate _Helper for 2 inner Activity classes"() { + def "generate for 2 inner Activity classes"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "Wrapper", """ @@ -591,8 +673,8 @@ public final class IntentBuilderSpecification } """, [ - E : Extra.class, - _ : [Activity.class] + E: Extra.class, + _: [Activity.class] ] ) diff --git a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/parcel/ParcelHelperSpecification.groovy b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/parcel/ParcelHelperSpecification.groovy index f6c9304..20ac5f0 100644 --- a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/parcel/ParcelHelperSpecification.groovy +++ b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/parcel/ParcelHelperSpecification.groovy @@ -113,9 +113,7 @@ public final class ParcelHelperSpecification ) expect: - assertFiles(input) - .with(BladeProcessor.Module.PARCEL) - .compilesWithoutError() + compilesWithoutErrorAndDoesntGenerate("com.example", "MyClass_Helper", BladeProcessor.Module.PARCEL, input) } def "generate _Helper for a class with fields"() { diff --git a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/state/StateHelperSpecification.groovy b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/state/StateHelperSpecification.groovy index eacb25d..616e586 100644 --- a/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/state/StateHelperSpecification.groovy +++ b/core-compiler/src/test/groovy/eu/f3rog/blade/compiler/state/StateHelperSpecification.groovy @@ -7,6 +7,7 @@ import android.os.Bundle import android.os.Parcelable import android.view.View import blade.Blade +import blade.Bundler import blade.State import blade.mvp.IPresenter import blade.mvp.IView @@ -15,12 +16,10 @@ import eu.f3rog.blade.compiler.BladeProcessor import eu.f3rog.blade.compiler.ErrorMsg import eu.f3rog.blade.compiler.util.JavaFile import eu.f3rog.blade.core.BundleWrapper -import blade.Bundler import eu.f3rog.blade.core.Weave import spock.lang.Unroll import javax.tools.JavaFileObject -import javax.tools.StandardLocation public final class StateHelperSpecification extends BaseSpecification { @@ -66,15 +65,66 @@ public final class StateHelperSpecification ) expect: - try { - assertFiles(input) - .with(BladeProcessor.Module.STATE) - .compilesWithoutError() - .and() - .generatesFileNamed(StandardLocation.CLASS_OUTPUT, "com.example", "MyClass_Helper.class") - } catch (AssertionError e) { - assert e.getMessage().contains("Did not find a generated file corresponding to MyClass_Helper.class in package com.example") - } + compilesWithoutErrorAndDoesntGenerate("com.example", "MyClass_Helper", BladeProcessor.Module.STATE, input) + } + + @Unroll + def "generate for a class with 1 @State #type"() { + given: + final JavaFileObject input = JavaFile.newFile("com.example", "MyClass", + """ + public class #T { + + @#S $type mField; + } + """, + [ + S: State.class + ] + ) + + expect: + final JavaFileObject expected = JavaFile.newGeneratedFile("com.example", "MyClass_Helper", + """ + abstract class #T { + public static void saveState(#I target, Bundle state) { + if (state == null) { + throw new #E("State cannot be null!"); + } + BundleWrapper bundleWrapper = BundleWrapper.from(state); + bundleWrapper.put("", target.mField); + } + + public static void restoreState(#I target, Bundle state) { + if (state == null) { + return; + } + BundleWrapper bundleWrapper = BundleWrapper.from(state); + target.mField = bundleWrapper.get("", target.mField); + } + } + """, + [ + I: input, + E: IllegalArgumentException.class, + _: [Bundle.class, BundleWrapper.class] + ] + ) + + assertFiles(input) + .with(BladeProcessor.Module.STATE) + .compilesWithoutError() + .and() + .generatesSources(expected) + + where: + type | _ + 'byte' | _ + 'boolean' | _ + 'int' | _ + 'long' | _ + 'float' | _ + 'double' | _ } def "generate for a class with 2 @State"() { @@ -203,7 +253,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate for an Activity with 2 @State"() { + def "generate for an Activity class with 2 @State"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyActivity", """ @@ -266,7 +316,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate for a Fragment with 2 @State"() { + def "generate for a Fragment class with 2 @State"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyFragment", """ @@ -329,7 +379,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate for a Presenter with 2 @State"() { + def "generate for a Presenter class with 2 @State"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyPresenter", """ @@ -393,7 +443,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate for a View with 2 @State"() { + def "generate for a View class with 2 @State"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyView", """ @@ -459,7 +509,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate for a View with 2 @State with onSaveInstanceState()"() { + def "generate for a View class with 2 @State with onSaveInstanceState()"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyView", """ @@ -530,7 +580,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate for a View with 2 @State with onRestoreInstanceState()"() { + def "generate for a View class with 2 @State with onRestoreInstanceState()"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyView", """ @@ -600,7 +650,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate for a View with 2 @State with onSaveInstanceState() and onRestoreInstanceState()"() { + def "generate for a View class with 2 @State with onSaveInstanceState() and onRestoreInstanceState()"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyView", """ @@ -675,7 +725,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate _Helper for a generic Activity with 2 @Extra"() { + def "generate _Helper for a generic Activity class with 2 @State"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyClass", """ @@ -686,8 +736,8 @@ public final class StateHelperSpecification } """, [ - S : State.class, - _ : [] + S: State.class, + _: [] ] ) @@ -716,9 +766,9 @@ public final class StateHelperSpecification } """, [ - I : input, - E : IllegalArgumentException.class, - _ : [Bundle.class, BundleWrapper.class] + I: input, + E: IllegalArgumentException.class, + _: [Bundle.class, BundleWrapper.class] ] ) @@ -729,7 +779,7 @@ public final class StateHelperSpecification .generatesSources(expected) } - def "generate _Helper for a generic Activity field with 2 @Extra"() { + def "generate _Helper for a generic Activity class with 2 @State"() { given: final JavaFileObject input = JavaFile.newFile("com.example", "MyClass", """ @@ -740,8 +790,8 @@ public final class StateHelperSpecification } """, [ - S : State.class, - _ : [Serializable.class] + S: State.class, + _: [Serializable.class] ] ) @@ -770,9 +820,9 @@ public final class StateHelperSpecification } """, [ - I : input, - E : IllegalArgumentException.class, - _ : [Bundle.class, BundleWrapper.class, Serializable.class] + I: input, + E: IllegalArgumentException.class, + _: [Bundle.class, BundleWrapper.class, Serializable.class] ] ) @@ -801,8 +851,8 @@ public final class StateHelperSpecification } """, [ - S : State.class, - _ : [Context.class, View.class] + S: State.class, + _: [Context.class, View.class] ] ) @@ -840,9 +890,9 @@ public final class StateHelperSpecification } """, [ - I : input, - E : IllegalArgumentException.class, - _ : [Bundle.class, BundleWrapper.class, Weave.class] + I: input, + E: IllegalArgumentException.class, + _: [Bundle.class, BundleWrapper.class, Weave.class] ] ) @@ -867,8 +917,8 @@ public final class StateHelperSpecification } """, [ - S : State.class, - _ : [] + S: State.class, + _: [] ] ) @@ -897,9 +947,9 @@ public final class StateHelperSpecification } """, [ - I : input, - E : IllegalArgumentException.class, - _ : [Bundle.class, BundleWrapper.class] + I: input, + E: IllegalArgumentException.class, + _: [Bundle.class, BundleWrapper.class] ] ) @@ -930,8 +980,8 @@ public final class StateHelperSpecification } """, [ - S : State.class, - _ : [] + S: State.class, + _: [] ] ) @@ -960,9 +1010,9 @@ public final class StateHelperSpecification } """, [ - I : input, - E : IllegalArgumentException.class, - _ : [Bundle.class, BundleWrapper.class] + I: input, + E: IllegalArgumentException.class, + _: [Bundle.class, BundleWrapper.class] ] ) final JavaFileObject expected2 = JavaFile.newGeneratedFile("com.example", "Wrapper_MyClass2_Helper", @@ -989,9 +1039,9 @@ public final class StateHelperSpecification } """, [ - I : input, - E : IllegalArgumentException.class, - _ : [Bundle.class, BundleWrapper.class] + I: input, + E: IllegalArgumentException.class, + _: [Bundle.class, BundleWrapper.class] ] ) diff --git a/gradle.properties b/gradle.properties index c61a456..a08624e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1536M LIB_GROUP_ID = eu.f3rog.blade ARTIFACT_ID = none -LIB_VERSION = 2.6.3 +LIB_VERSION = 2.6.4 LIB_VERSION_DESC = Android Library for Boilerplate Destruction diff --git a/plugin/src/main/groovy/eu/f3rog/blade/plugin/BladePlugin.groovy b/plugin/src/main/groovy/eu/f3rog/blade/plugin/BladePlugin.groovy index d86973b..b002ea2 100644 --- a/plugin/src/main/groovy/eu/f3rog/blade/plugin/BladePlugin.groovy +++ b/plugin/src/main/groovy/eu/f3rog/blade/plugin/BladePlugin.groovy @@ -32,7 +32,7 @@ public final class BladePlugin public static String ERROR_CONFIG_FILE_IS_MISSING = "Blade configuration file is missing! (more info here: https://github.com/FrantisekGazo/Blade/wiki#1-create-configuration-file)" public static String LIB_GROUP_ID = "eu.f3rog.blade" - public static String LIB_VERSION = "2.6.3" + public static String LIB_VERSION = "2.6.4" public static String LIB_CONFIG_FILE_NAME = "blade" public static String[] LIB_MODULES = ["arg", "extra", "mvp", "parcel", "state"] diff --git a/plugin/src/main/java/eu/f3rog/blade/weaving/interfaces/WeavedMvpUiIW.java b/plugin/src/main/java/eu/f3rog/blade/weaving/interfaces/WeavedMvpUiIW.java index 1a76da8..51c1167 100644 --- a/plugin/src/main/java/eu/f3rog/blade/weaving/interfaces/WeavedMvpUiIW.java +++ b/plugin/src/main/java/eu/f3rog/blade/weaving/interfaces/WeavedMvpUiIW.java @@ -120,19 +120,33 @@ public final void weave(CtClass interfaceClass, CtClass targetClass, JavassistHe protected abstract void weave(CtClass targetClass, JavassistHelper javassistHelper, List presenterFieldNames) throws CannotCompileException, NotFoundException, AfterBurnerImpossibleException; - private List getPresenterFieldNames(CtClass targetClass) throws NotFoundException { - List presenterFieldNames = new ArrayList<>(); - - ClassPool classPool = targetClass.getClassPool(); - CtField[] declaredFields = targetClass.getDeclaredFields(); - CtClass presenterInterface = classPool.get("blade.mvp.IPresenter"); - - for (CtField declaredField : declaredFields) { - if (declaredField.hasAnnotation(Inject.class) && declaredField.getType().subtypeOf(presenterInterface)) { - presenterFieldNames.add(declaredField.getName()); + /** + * Returns all presenter field names (also the ones defined by parent classes) because dagger injects all of them. + * + * @param targetClass Target class + * @return List of field names. + * @throws NotFoundException + */ + private List getPresenterFieldNames(final CtClass targetClass) throws NotFoundException { + final List allPresenterFieldNames = new ArrayList<>(); + + final ClassPool classPool = targetClass.getClassPool(); + final CtClass presenterInterface = classPool.get("blade.mvp.IPresenter"); + + CtClass currentClass = targetClass; + while (currentClass != null) { + final CtField[] declaredFields = currentClass.getDeclaredFields(); + for (final CtField declaredField : declaredFields) { + if (!declaredField.visibleFrom(targetClass)) { + continue; + } + if (declaredField.hasAnnotation(Inject.class) && declaredField.getType().subtypeOf(presenterInterface)) { + allPresenterFieldNames.add(declaredField.getName()); + } } + currentClass = currentClass.getSuperclass(); } - return presenterFieldNames; + return allPresenterFieldNames; } }