Skip to content

Commit 2aa3b2c

Browse files
committed
log the arguments and return value of the @trace'd method
1 parent 8a0e735 commit 2aa3b2c

1 file changed

Lines changed: 95 additions & 9 deletions

File tree

  • AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/TraceHandler.java‎

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
import static org.androidannotations.helper.AndroidConstants.LOG_VERBOSE;
2222
import static org.androidannotations.helper.AndroidConstants.LOG_WARN;
2323

24+
import java.util.ArrayList;
25+
import java.util.Arrays;
26+
import java.util.List;
27+
2428
import javax.annotation.processing.ProcessingEnvironment;
2529
import javax.lang.model.element.Element;
2630
import javax.lang.model.element.ExecutableElement;
@@ -40,6 +44,7 @@
4044
import com.sun.codemodel.JInvocation;
4145
import com.sun.codemodel.JMethod;
4246
import com.sun.codemodel.JTryBlock;
47+
import com.sun.codemodel.JType;
4348
import com.sun.codemodel.JVar;
4449

4550
public class TraceHandler extends BaseAnnotationHandler<EComponentHolder> {
@@ -80,21 +85,28 @@ public void process(Element element, EComponentHolder holder) throws Exception {
8085
JInvocation currentTimeInvoke = classes().SYSTEM.staticInvoke("currentTimeMillis");
8186
JBlock _thenBody = ifStatement._then();
8287

83-
String methodName = "[" + element.toString() + "]";
84-
8588
// Log In
8689
String logMethodName = logMethodNameFromLevel(level);
8790
JInvocation logEnterInvoke = classes().LOG.staticInvoke(logMethodName);
8891
logEnterInvoke.arg(tag);
8992

90-
JExpression enterMessage = JExpr.lit("Entering " + methodName);
91-
logEnterInvoke.arg(enterMessage);
93+
logEnterInvoke.arg(getEnterMessage(method, executableElement));
9294
_thenBody.add(logEnterInvoke);
9395
JVar startDeclaration = _thenBody.decl(codeModel().LONG, "start", currentTimeInvoke);
9496

95-
JTryBlock tryBlock = _thenBody._try();
96-
97-
tryBlock.body().add(previousMethodBody);
97+
JTryBlock tryBlock;
98+
99+
JVar result = null;
100+
if (method.type().fullName().equals("void")) {
101+
tryBlock = _thenBody._try();
102+
tryBlock.body().add(previousMethodBody);
103+
} else {
104+
JInvocation superCall = codeModelHelper.getSuperCall(holder, method);
105+
result = _thenBody.decl(refClass(Object.class), "result", JExpr._null());
106+
tryBlock = _thenBody._try();
107+
tryBlock.body().assign(result, superCall);
108+
tryBlock.body()._return(JExpr.cast(boxify(method.type()), result));
109+
}
98110

99111
JBlock finallyBlock = tryBlock._finally();
100112

@@ -103,15 +115,89 @@ public void process(Element element, EComponentHolder holder) throws Exception {
103115
JInvocation logExitInvoke = classes().LOG.staticInvoke(logMethodName);
104116
logExitInvoke.arg(tag);
105117

106-
JExpression exitMessage = JExpr.lit("Exiting " + methodName + ", duration in ms: ").plus(durationDeclaration);
107-
logExitInvoke.arg(exitMessage);
118+
logExitInvoke.arg(getExitMessage(executableElement, method, result, durationDeclaration));
108119
finallyBlock.add(logExitInvoke);
109120

110121
JBlock elseBlock = ifStatement._else();
111122

112123
elseBlock.add(previousMethodBody);
113124
}
114125

126+
private JClass boxify(JType type) throws ClassNotFoundException {
127+
return codeModel().parseType(type.fullName()).boxify();
128+
}
129+
130+
private JExpression getExitMessage(ExecutableElement element, JMethod method, JVar result, JVar duration) throws ClassNotFoundException {
131+
String methodName = getMethodName(element);
132+
133+
List<JVar> params = method.params();
134+
StringBuilder paramStr = new StringBuilder();
135+
for (int i = 0; i < params.size(); i++) {
136+
if (i > 0) {
137+
paramStr.append(", ");
138+
}
139+
JVar var = params.get(i);
140+
paramStr.append(var.type().name());
141+
}
142+
143+
methodName += "(" + paramStr.toString() + ")";
144+
145+
JInvocation format = refClass(String.class).staticInvoke("format");
146+
if (result == null) {
147+
format.arg("Exiting [" + methodName + "], duration in ms: %d");
148+
} else {
149+
format.arg("Exiting [" + methodName + " returning: %s], duration in ms: %d");
150+
if (method.type().isArray()) {
151+
JClass arraysClass = refClass(Arrays.class);
152+
format.arg(arraysClass.staticInvoke("toString").arg(JExpr.cast(boxify(method.type()), result)));
153+
} else {
154+
format.arg(result);
155+
}
156+
}
157+
158+
return format.arg(duration);
159+
}
160+
161+
private JExpression getEnterMessage(JMethod method, ExecutableElement element) {
162+
String methodName = getMethodName(element);
163+
164+
List<JVar> params = method.params();
165+
if (params.isEmpty()) {
166+
// early exit if the method has no parameters
167+
return JExpr.lit("Entering [" + methodName + "()]");
168+
}
169+
170+
JClass arraysClass = refClass(Arrays.class);
171+
StringBuilder paramStr = new StringBuilder();
172+
List<JExpression> paramExpressions = new ArrayList<JExpression>();
173+
for (int i = 0; i < params.size(); i++) {
174+
if (i > 0) {
175+
paramStr.append(", ");
176+
}
177+
JVar var = params.get(i);
178+
paramStr.append(var.name()).append(" = %s");
179+
if (var.type().isArray()) {
180+
paramExpressions.add(arraysClass.staticInvoke("toString").arg(var));
181+
} else {
182+
paramExpressions.add(var);
183+
}
184+
}
185+
186+
JInvocation format = refClass(String.class).staticInvoke("format");
187+
format.arg(JExpr.lit("Entering [" + methodName + "(" + paramStr + ")]"));
188+
for (JExpression expr : paramExpressions) {
189+
format.arg(expr);
190+
}
191+
192+
return format;
193+
}
194+
195+
private String getMethodName(ExecutableElement element) {
196+
String returnType = element.getReturnType().toString();
197+
String simpleName = element.getSimpleName().toString();
198+
return returnType + " " + simpleName;
199+
}
200+
115201
private String logMethodNameFromLevel(int level) {
116202
switch (level) {
117203
case LOG_DEBUG:

0 commit comments

Comments
 (0)