Skip to content

Commit dae39a3

Browse files
committed
Implementing a way to have multiple annotations on one method
1 parent 4f32944 commit dae39a3

7 files changed

Lines changed: 107 additions & 29 deletions

File tree

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,6 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
348348
for (AndroidRes androidRes : AndroidRes.values()) {
349349
modelValidator.register(new ResValidator(androidRes, processingEnv, rClass));
350350
}
351-
modelValidator.register(new RunnableValidator(UiThreadDelayed.class, processingEnv));
352-
modelValidator.register(new RunnableValidator(UiThread.class, processingEnv));
353-
modelValidator.register(new RunnableValidator(Background.class, processingEnv));
354351
modelValidator.register(new TransactionalValidator(processingEnv));
355352
modelValidator.register(new ExtraValidator(processingEnv));
356353
modelValidator.register(new SystemServiceValidator(processingEnv, androidSystemServices));
@@ -371,6 +368,9 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
371368
modelValidator.register(new OptionsItemValidator(processingEnv, rClass));
372369
modelValidator.register(new NoTitleValidator(processingEnv));
373370
modelValidator.register(new FullscreenValidator(processingEnv));
371+
modelValidator.register(new RunnableValidator(UiThreadDelayed.class, processingEnv));
372+
modelValidator.register(new RunnableValidator(UiThread.class, processingEnv));
373+
modelValidator.register(new RunnableValidator(Background.class, processingEnv));
374374
modelValidator.register(new TraceValidator(processingEnv));
375375
return modelValidator;
376376
}
@@ -401,9 +401,6 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
401401
for (AndroidRes androidRes : AndroidRes.values()) {
402402
modelProcessor.register(new ResProcessor(androidRes, rClass));
403403
}
404-
modelProcessor.register(new UiThreadProcessor());
405-
modelProcessor.register(new UiThreadDelayedProcessor());
406-
modelProcessor.register(new BackgroundProcessor());
407404
modelProcessor.register(new TransactionalProcessor());
408405
modelProcessor.register(new ExtraProcessor());
409406
modelProcessor.register(new SystemServiceProcessor(androidSystemServices));
@@ -423,6 +420,9 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
423420
modelProcessor.register(new NoTitleProcessor());
424421
modelProcessor.register(new FullscreenProcessor());
425422
modelProcessor.register(new TraceProcessor());
423+
modelProcessor.register(new UiThreadProcessor());
424+
modelProcessor.register(new UiThreadDelayedProcessor());
425+
modelProcessor.register(new BackgroundProcessor());
426426
return modelProcessor;
427427
}
428428

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/APTCodeModelHelper.java‎

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.googlecode.androidannotations.helper;
1717

18+
import java.lang.reflect.Field;
1819
import java.util.ArrayList;
1920
import java.util.List;
2021

@@ -26,12 +27,13 @@
2627
import com.googlecode.androidannotations.processing.EBeanHolder;
2728
import com.sun.codemodel.JBlock;
2829
import com.sun.codemodel.JClass;
29-
import com.sun.codemodel.JCodeModel;
30+
import com.sun.codemodel.JDefinedClass;
3031
import com.sun.codemodel.JExpr;
3132
import com.sun.codemodel.JExpression;
3233
import com.sun.codemodel.JInvocation;
3334
import com.sun.codemodel.JMethod;
3435
import com.sun.codemodel.JMod;
36+
import com.sun.codemodel.JStatement;
3537
import com.sun.codemodel.JType;
3638
import com.sun.codemodel.JVar;
3739

@@ -62,31 +64,74 @@ public JClass typeMirrorToJClass(TypeMirror type, EBeanHolder holder) {
6264
}
6365
}
6466

67+
public static class Parameter {
68+
public final String name;
69+
public final JClass jClass;
70+
71+
public Parameter(String name, JClass jClass) {
72+
this.name = name;
73+
this.jClass = jClass;
74+
}
75+
}
76+
6577
public JMethod overrideAnnotatedMethod(ExecutableElement executableElement, EBeanHolder holder) {
78+
6679
String methodName = executableElement.getSimpleName().toString();
6780

6881
JClass returnType = typeMirrorToJClass(executableElement.getReturnType(), holder);
6982

83+
List<Parameter> parameters = new ArrayList<Parameter>();
84+
for (VariableElement parameter : executableElement.getParameters()) {
85+
String parameterName = parameter.getSimpleName().toString();
86+
JClass parameterClass = typeMirrorToJClass(parameter.asType(), holder);
87+
parameters.add(new Parameter(parameterName, parameterClass));
88+
}
89+
90+
JMethod existingMethod = findAlreadyGeneratedMethod(holder.eBean, methodName, parameters);
91+
92+
if (existingMethod != null) {
93+
return existingMethod;
94+
}
95+
7096
JMethod method = holder.eBean.method(JMod.PUBLIC, returnType, methodName);
7197
method.annotate(Override.class);
7298

73-
List<JVar> parameters = new ArrayList<JVar>();
99+
List<JVar> methodParameters = new ArrayList<JVar>();
74100
for (VariableElement parameter : executableElement.getParameters()) {
75101
String parameterName = parameter.getSimpleName().toString();
76102
JClass parameterClass = typeMirrorToJClass(parameter.asType(), holder);
77103
JVar param = method.param(JMod.FINAL, parameterClass, parameterName);
78-
parameters.add(param);
104+
methodParameters.add(param);
79105
}
80106

81107
for (TypeMirror superThrownType : executableElement.getThrownTypes()) {
82108
JClass thrownType = typeMirrorToJClass(superThrownType, holder);
83109
method._throws(thrownType);
84110
}
111+
112+
callSuperMethod(method, holder, method.body());
85113

86114
return method;
87115
}
88116

89-
public void callSuperMethod(JMethod superMethod, JCodeModel codeModel, EBeanHolder holder, JBlock callBlock) {
117+
private JMethod findAlreadyGeneratedMethod(JDefinedClass definedClass, String methodName, List<Parameter> parameters) {
118+
method: for (JMethod method : definedClass.methods()) {
119+
if (method.name().equals(methodName) && method.params().size() == parameters.size()) {
120+
int i = 0;
121+
for (JVar param : method.params()) {
122+
String searchedParamType = parameters.get(i).jClass.name();
123+
if (!param.type().name().equals(searchedParamType)) {
124+
continue method;
125+
}
126+
i++;
127+
}
128+
return method;
129+
}
130+
}
131+
return null;
132+
}
133+
134+
public void callSuperMethod(JMethod superMethod, EBeanHolder holder, JBlock callBlock) {
90135
JExpression activitySuper = holder.eBean.staticRef("super");
91136
JInvocation superCall = JExpr.invoke(activitySuper, superMethod);
92137

@@ -101,5 +146,24 @@ public void callSuperMethod(JMethod superMethod, JCodeModel codeModel, EBeanHold
101146
callBlock._return(superCall);
102147
}
103148
}
149+
150+
public JBlock removeBody(JMethod method) {
151+
JBlock body = method.body();
152+
try {
153+
Field bodyField = JMethod.class.getDeclaredField("body");
154+
bodyField.setAccessible(true);
155+
bodyField.set(method, null);
156+
} catch (Exception e) {
157+
throw new RuntimeException(e);
158+
}
159+
160+
JBlock clonedBody = new JBlock(false, false);
161+
162+
for(Object statement : body.getContents()) {
163+
clonedBody.add((JStatement) statement);
164+
}
165+
166+
return clonedBody;
167+
}
104168

105169
}

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/BackgroundProcessor.java‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
5353
// Method
5454
ExecutableElement executableElement = (ExecutableElement) element;
5555
JMethod backgroundMethod = helper.overrideAnnotatedMethod(executableElement, holder);
56+
57+
JBlock previousMethodBody = helper.removeBody(backgroundMethod);
5658

5759
JDefinedClass anonymousRunnableClass = codeModel.anonymousClass(Runnable.class);
5860

@@ -61,8 +63,8 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
6163

6264
JBlock runMethodBody = runMethod.body();
6365
JTryBlock runTry = runMethodBody._try();
64-
65-
helper.callSuperMethod(backgroundMethod, codeModel, holder, runTry.body());
66+
67+
runTry.body().add(previousMethodBody);
6668

6769
JCatchBlock runCatch = runTry._catch(holder.refClass(RuntimeException.class));
6870
JVar exceptionParam = runCatch.param("e");

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/TraceProcessor.java‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
5757
JClass systemClass = holder.refClass(System.class);
5858

5959
JMethod method = helper.overrideAnnotatedMethod(executableElement, holder);
60+
61+
JBlock previousMethodBody = helper.removeBody(method);
6062

6163
JBlock methodBody = method.body();
62-
64+
6365
JInvocation isLoggableInvocation = logClass.staticInvoke("isLoggable");
6466
isLoggableInvocation.arg(JExpr.lit(tag)).arg(logLevelFromInt(level, logClass));
6567

@@ -69,8 +71,9 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
6971
JVar startDeclaration = ifStatement._then().decl(codeModel.LONG, "start", currentTimeInvoke);
7072

7173
JTryBlock tryBlock = ifStatement._then()._try();
72-
helper.callSuperMethod(method, codeModel, holder, tryBlock.body());
73-
74+
75+
tryBlock.body().add(previousMethodBody);
76+
7477
JBlock finallyBlock = tryBlock._finally();
7578

7679
JVar durationDeclaration = finallyBlock.decl(codeModel.LONG, "duration", currentTimeInvoke.minus(startDeclaration));
@@ -85,7 +88,8 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
8588
finallyBlock.add(logInvoke);
8689

8790
JBlock elseBlock = ifStatement._else();
88-
helper.callSuperMethod(method, codeModel, holder, elseBlock);
91+
92+
elseBlock.add(previousMethodBody);
8993
}
9094

9195
private String logMethodNameFromLevel(int level) {

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/UiThreadProcessor.java‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
5252
// Method
5353
ExecutableElement executableElement = (ExecutableElement) element;
5454
JMethod method = helper.overrideAnnotatedMethod(executableElement, holder);
55+
56+
JBlock previousMethodBody = helper.removeBody(method);
5557

5658
JDefinedClass anonymousRunnableClass = codeModel.anonymousClass(Runnable.class);
5759

@@ -60,8 +62,8 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
6062

6163
JBlock runMethodBody = runMethod.body();
6264
JTryBlock runTry = runMethodBody._try();
63-
64-
helper.callSuperMethod(method, codeModel, holder, runTry.body());
65+
66+
runTry.body().add(previousMethodBody);
6567

6668
JCatchBlock runCatch = runTry._catch(holder.refClass(RuntimeException.class));
6769
JVar exceptionParam = runCatch.param("e");

‎AndroidAnnotations/functional-test-1-5/src/main/java/com/googlecode/androidannotations/test15/TracedActivity.java‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import com.googlecode.androidannotations.annotations.EActivity;
2727
import com.googlecode.androidannotations.annotations.Trace;
28+
import com.googlecode.androidannotations.annotations.UiThread;
2829

2930
@EActivity
3031
public class TracedActivity extends Activity {
@@ -36,9 +37,8 @@ public class TracedActivity extends Activity {
3637
public boolean voidTracedMethodWarnCalled = false;
3738
public boolean voidTracedMethodErrorCalled = false;
3839
public boolean voidTracedMethodInfoCalled = false;
39-
public boolean overLoaddedMethodInt = false;
40-
public boolean overLoaddedMethodIntFLoat = false;
41-
40+
public boolean overloadedMethodInt = false;
41+
public boolean overloadedMethodIntFLoat = false;
4242

4343
@Trace
4444
Object tracedMethod(List<Map<String, List<Set<Void>>>> param1, Void param2) throws IOException {
@@ -78,11 +78,17 @@ void voidTracedMethodInfo() {
7878

7979
@Trace
8080
void overloadedMethod(int x) {
81-
overLoaddedMethodInt = true;
81+
overloadedMethodInt = true;
8282
}
8383

8484
@Trace
8585
void overloadedMethod(int x, float f) {
86-
overLoaddedMethodIntFLoat = true;
86+
overloadedMethodIntFLoat = true;
87+
}
88+
89+
@Trace
90+
@UiThread
91+
void mixedMethod() {
92+
8793
}
8894
}

‎AndroidAnnotations/functional-test-1-5/src/test/java/com/googlecode/androidannotations/test15/TracedActivityTest.java‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ public void servicesAreInjected() throws IOException {
6060
activity.voidTracedMethodWarn();
6161
assertThat(activity.voidTracedMethodWarnCalled).isTrue();
6262

63-
assertThat(activity.overLoaddedMethodInt).isFalse();
64-
activity.overLoaddedMethod(0);
65-
assertThat(activity.overLoaddedMethodInt).isTrue();
63+
assertThat(activity.overloadedMethodInt).isFalse();
64+
activity.overloadedMethod(0);
65+
assertThat(activity.overloadedMethodInt).isTrue();
6666

67-
assertThat(activity.overLoaddedMethodIntFLoat).isFalse();
68-
activity.overLoaddedMethod(0, 0f);
69-
assertThat(activity.overLoaddedMethodIntFLoat).isTrue();
67+
assertThat(activity.overloadedMethodIntFLoat).isFalse();
68+
activity.overloadedMethod(0, 0f);
69+
assertThat(activity.overloadedMethodIntFLoat).isTrue();
7070
}
7171

7272

0 commit comments

Comments
 (0)