Skip to content

Commit 804bff7

Browse files
committed
allow to inject fragment arguments into @FragmentArg annotated method
1 parent 4d9d2fc commit 804bff7

2 files changed

Lines changed: 51 additions & 25 deletions

File tree

  • AndroidAnnotations/androidannotations-core

‎AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/annotations/FragmentArg.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
* @see FragmentByTag
7474
*/
7575
@Retention(RetentionPolicy.CLASS)
76-
@Target(ElementType.FIELD)
76+
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
7777
public @interface FragmentArg {
7878

7979
/**

‎AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/core/handler/FragmentArgHandler.java‎

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,43 +22,64 @@
2222
import static com.helger.jcodemodel.JMod.STATIC;
2323

2424
import javax.lang.model.element.Element;
25+
import javax.lang.model.element.ElementKind;
26+
import javax.lang.model.type.DeclaredType;
2527
import javax.lang.model.type.TypeMirror;
2628

2729
import org.androidannotations.AndroidAnnotationsEnvironment;
2830
import org.androidannotations.ElementValidation;
2931
import org.androidannotations.annotations.FragmentArg;
3032
import org.androidannotations.handler.BaseAnnotationHandler;
33+
import org.androidannotations.handler.MethodInjectionHandler;
3134
import org.androidannotations.helper.BundleHelper;
3235
import org.androidannotations.helper.CaseHelper;
36+
import org.androidannotations.helper.InjectHelper;
3337
import org.androidannotations.holder.EFragmentHolder;
3438

3539
import com.helger.jcodemodel.AbstractJClass;
40+
import com.helger.jcodemodel.IJAssignmentTarget;
3641
import com.helger.jcodemodel.IJExpression;
3742
import com.helger.jcodemodel.JBlock;
43+
import com.helger.jcodemodel.JConditional;
3844
import com.helger.jcodemodel.JDefinedClass;
3945
import com.helger.jcodemodel.JExpr;
4046
import com.helger.jcodemodel.JFieldRef;
4147
import com.helger.jcodemodel.JFieldVar;
4248
import com.helger.jcodemodel.JMethod;
49+
import com.helger.jcodemodel.JOp;
4350
import com.helger.jcodemodel.JVar;
4451

45-
public class FragmentArgHandler extends BaseAnnotationHandler<EFragmentHolder> {
52+
public class FragmentArgHandler extends BaseAnnotationHandler<EFragmentHolder>implements MethodInjectionHandler<EFragmentHolder> {
53+
54+
private final InjectHelper<EFragmentHolder> injectHelper;
4655

4756
public FragmentArgHandler(AndroidAnnotationsEnvironment environment) {
4857
super(FragmentArg.class, environment);
58+
injectHelper = new InjectHelper<>(validatorHelper, this);
4959
}
5060

5161
@Override
5262
public void validate(Element element, ElementValidation validation) {
53-
validatorHelper.enclosingElementHasEFragment(element, validation);
63+
injectHelper.validate(FragmentArg.class, element, validation);
5464

5565
validatorHelper.isNotPrivate(element, validation);
5666

57-
validatorHelper.canBePutInABundle(element, validation);
67+
Element param = injectHelper.getParam(element);
68+
validatorHelper.canBePutInABundle(param, validation);
5869
}
5970

6071
@Override
6172
public void process(Element element, EFragmentHolder holder) {
73+
injectHelper.process(element, holder);
74+
}
75+
76+
@Override
77+
public JBlock getInvocationBlock(EFragmentHolder holder) {
78+
return holder.getInjectArgsBlock();
79+
}
80+
81+
@Override
82+
public void assignValue(JBlock targetBlock, IJAssignmentTarget fieldRef, EFragmentHolder holder, Element element, Element param) {
6283
FragmentArg annotation = element.getAnnotation(FragmentArg.class);
6384
String argKey = annotation.value();
6485
String fieldName = element.getSimpleName().toString();
@@ -67,12 +88,32 @@ public void process(Element element, EFragmentHolder holder) {
6788
argKey = fieldName;
6889
}
6990

70-
TypeMirror actualType = codeModelHelper.getActualType(element, holder);
91+
DeclaredType enclosingClassType;
92+
if (param.getKind() == ElementKind.PARAMETER) {
93+
enclosingClassType = (DeclaredType) param.getEnclosingElement().getEnclosingElement().asType();
94+
} else {
95+
enclosingClassType = (DeclaredType) param.getEnclosingElement().asType();
96+
}
97+
TypeMirror actualType = codeModelHelper.getActualType(param, enclosingClassType, holder);
7198

7299
BundleHelper bundleHelper = new BundleHelper(getEnvironment(), actualType);
73-
JFieldVar argKeyStaticField = createStaticArgField(holder, argKey, fieldName);
74-
injectArgInComponent(element, holder, bundleHelper, argKeyStaticField, fieldName);
75-
createBuilderInjectionMethod(element, holder, bundleHelper, argKeyStaticField, fieldName);
100+
JFieldVar extraKeyStaticField = createStaticArgField(holder, argKey, fieldName);
101+
createBuilderInjectionMethod(param, actualType, holder, bundleHelper, extraKeyStaticField, fieldName);
102+
103+
AbstractJClass elementClass = codeModelHelper.typeMirrorToJClass(actualType);
104+
105+
JVar bundle = holder.getInjectBundleArgs();
106+
JMethod injectExtrasMethod = holder.getInjectArgsMethod();
107+
108+
IJExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromBundle(elementClass, bundle, extraKeyStaticField, injectExtrasMethod);
109+
110+
JConditional conditional = targetBlock._if(JExpr.invoke(bundle, "containsKey").arg(extraKeyStaticField));
111+
conditional._then().add(fieldRef.assign(restoreMethodCall));
112+
}
113+
114+
@Override
115+
public void validateEnclosingElement(Element element, ElementValidation valid) {
116+
validatorHelper.enclosingElementHasEFragment(element, valid);
76117
}
77118

78119
private JFieldVar createStaticArgField(EFragmentHolder holder, String argKey, String fieldName) {
@@ -85,25 +126,10 @@ private JFieldVar createStaticArgField(EFragmentHolder holder, String argKey, St
85126
return holder.getGeneratedClass().field(PUBLIC | STATIC | FINAL, getClasses().STRING, staticFieldName, lit(argKey));
86127
}
87128

88-
private void injectArgInComponent(Element element, EFragmentHolder holder, BundleHelper bundleHelper, JFieldVar extraKeyStaticField, String fieldName) {
89-
TypeMirror elementType = codeModelHelper.getActualType(element, holder);
90-
AbstractJClass elementClass = codeModelHelper.typeMirrorToJClass(elementType);
91-
92-
JVar bundle = holder.getInjectBundleArgs();
93-
JBlock injectExtrasBlock = holder.getInjectArgsBlock();
94-
JMethod injectExtrasMethod = holder.getInjectArgsMethod();
95-
JFieldRef extraField = JExpr.ref(fieldName);
96-
97-
JBlock ifContainsKey = injectExtrasBlock._if(JExpr.invoke(bundle, "containsKey").arg(extraKeyStaticField))._then();
98-
IJExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromBundle(elementClass, bundle, extraKeyStaticField, injectExtrasMethod);
99-
ifContainsKey.assign(extraField, restoreMethodCall);
100-
}
101-
102-
private void createBuilderInjectionMethod(Element element, EFragmentHolder holder, BundleHelper bundleHelper, JFieldVar argKeyStaticField, String fieldName) {
129+
private void createBuilderInjectionMethod(Element element, TypeMirror actualType, EFragmentHolder holder, BundleHelper bundleHelper, JFieldVar argKeyStaticField, String fieldName) {
103130
JDefinedClass builderClass = holder.getBuilderClass();
104131
JFieldRef builderArgsField = holder.getBuilderArgsField();
105-
TypeMirror type = codeModelHelper.getActualType(element, holder);
106-
AbstractJClass paramClass = codeModelHelper.typeMirrorToJClass(type);
132+
AbstractJClass paramClass = codeModelHelper.typeMirrorToJClass(actualType);
107133

108134
JMethod method = builderClass.method(PUBLIC, holder.narrow(builderClass), fieldName);
109135
JVar arg = method.param(paramClass, fieldName);

0 commit comments

Comments
 (0)