[slf4j-dev] svn commit: r1257 - slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation
ravn at slf4j.org
ravn at slf4j.org
Sun Dec 21 19:17:04 CET 2008
Author: ravn
Date: Sun Dec 21 19:17:04 2008
New Revision: 1257
Modified:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
Log:
Now is robust against exceptions in parameter rendering by
keeping a WeakHashMap of those classes which cannot be rendered.
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java Sun Dec 21 19:17:04 2008
@@ -15,144 +15,152 @@
*/
public class JavassistHelper {
- /**
- * Create a javaassist source snippet which either is empty (for anything
- * which does not return a value) or a explanatory text around the $_
- * javaassist return value variable.
- *
- * @param method
- * descriptor of method
- * @return source snippet
- * @throws NotFoundException
- */
- public static String returnValue(CtBehavior method) throws NotFoundException {
-
- String returnValue = "";
- if (methodReturnsValue(method)) {
- returnValue = " returns: \" + $_ + \".";
- }
- return returnValue;
- }
-
- /**
- * determine if the given method returns a value, and return true if so. false
- * otherwise.
- *
- * @param method
- * @return
- * @throws NotFoundException
- */
- private static boolean methodReturnsValue(CtBehavior method)
- throws NotFoundException {
-
- if (method instanceof CtMethod == false) {
- return false;
- }
-
- CtClass returnType = ((CtMethod) method).getReturnType();
- String returnTypeName = returnType.getName();
-
- boolean isVoidMethod = "void".equals(returnTypeName);
-
- boolean methodReturnsValue = isVoidMethod == false;
- return methodReturnsValue;
- }
-
- /**
- * Return javaassist source snippet which lists all the parameters and their
- * values. If available the source names are extracted from the debug
- * information and used, otherwise just a number is shown.
- *
- * @param method
- * @return
- * @throws NotFoundException
- */
- public static String getSignature(CtBehavior method) throws NotFoundException {
-
- CtClass parameterTypes[] = method.getParameterTypes();
-
- CodeAttribute codeAttribute = method.getMethodInfo().getCodeAttribute();
-
- LocalVariableAttribute locals = null;
-
- if (codeAttribute != null) {
- AttributeInfo attribute;
- attribute = codeAttribute.getAttribute("LocalVariableTable");
- locals = (LocalVariableAttribute) attribute;
- }
-
- String methodName = method.getName();
-
- StringBuffer sb = new StringBuffer(methodName + "(\" ");
- for (int i = 0; i < parameterTypes.length; i++) {
- if (i > 0) {
- // add a comma and a space between printed values
- sb.append(" + \", \" ");
- }
-
- CtClass parameterType = parameterTypes[i];
- boolean isArray = parameterType.isArray();
- CtClass arrayType = parameterType.getComponentType();
- if (isArray) {
- while (arrayType.isArray()) {
- arrayType = arrayType.getComponentType();
- }
- }
-
- sb.append(" + \"");
- sb.append(parameterNameFor(method, locals, i));
- sb.append("\" + \"=");
-
- // use Arrays.asList() to render array of objects.
- if (isArray && !arrayType.isPrimitive()) {
- sb.append("\"+ java.util.Arrays.asList($" + (i + 1) + ")");
- } else {
- sb.append("\"+ $" + (i + 1));
- }
- }
- sb.append("+\")");
-
- String signature = sb.toString();
- return signature;
- }
-
- /**
- * Determine the name of parameter with index i in the given method. Use the
- * locals attributes about local variables from the classfile. Note: This is
- * still work in progress.
- *
- * @param method
- * @param locals
- * @param i
- * @return the name of the parameter if available or a number if not.
- */
- static String parameterNameFor(CtBehavior method,
- LocalVariableAttribute locals, int i) {
-
- if (locals == null) {
- return Integer.toString(i + 1);
- }
-
- int modifiers = method.getModifiers();
-
- int j = i;
-
- if (Modifier.isSynchronized(modifiers)) {
- // skip object to synchronize upon.
- j++;
- // System.err.println("Synchronized");
- }
- if (Modifier.isStatic(modifiers) == false) {
- // skip "this"
- j++;
- // System.err.println("Instance");
- }
- String variableName = locals.variableName(j);
-// if (variableName.equals("this")) {
-// System.err.println("'this' returned as a parameter name for "
-// + method.getName() + " index " + j
-// + ", names are probably shifted. Please submit source for class in slf4j bugreport");
-// }
- return variableName;
- }
+ /**
+ * Create a javaassist source snippet which either is empty (for anything
+ * which does not return a value) or a explanatory text around the $_
+ * javaassist return value variable.
+ *
+ * @param method
+ * descriptor of method
+ * @return source snippet
+ * @throws NotFoundException
+ */
+ public static String returnValue(CtBehavior method)
+ throws NotFoundException {
+
+ String returnValue = "";
+ if (methodReturnsValue(method)) {
+ returnValue = " returns: \" + $_ + \".";
+ }
+ return returnValue;
+ }
+
+ /**
+ * determine if the given method returns a value, and return true if so.
+ * false otherwise.
+ *
+ * @param method
+ * @return
+ * @throws NotFoundException
+ */
+ private static boolean methodReturnsValue(CtBehavior method)
+ throws NotFoundException {
+
+ if (method instanceof CtMethod == false) {
+ return false;
+ }
+
+ CtClass returnType = ((CtMethod) method).getReturnType();
+ String returnTypeName = returnType.getName();
+
+ boolean isVoidMethod = "void".equals(returnTypeName);
+
+ boolean methodReturnsValue = isVoidMethod == false;
+ return methodReturnsValue;
+ }
+
+ /**
+ * Return javaassist source snippet which lists all the parameters and their
+ * values. If available the source names are extracted from the debug
+ * information and used, otherwise just a number is shown.
+ *
+ * @param method
+ * @return
+ * @throws NotFoundException
+ */
+ public static String getSignature(CtBehavior method)
+ throws NotFoundException {
+
+ CtClass parameterTypes[] = method.getParameterTypes();
+
+ CodeAttribute codeAttribute = method.getMethodInfo().getCodeAttribute();
+
+ LocalVariableAttribute locals = null;
+
+ if (codeAttribute != null) {
+ AttributeInfo attribute;
+ attribute = codeAttribute.getAttribute("LocalVariableTable");
+ locals = (LocalVariableAttribute) attribute;
+ }
+
+ String methodName = method.getName();
+
+ StringBuffer sb = new StringBuffer(methodName + "(\" ");
+ for (int i = 0; i < parameterTypes.length; i++) {
+ if (i > 0) {
+ // add a comma and a space between printed values
+ sb.append(" + \", \" ");
+ }
+
+ CtClass parameterType = parameterTypes[i];
+ boolean isArray = parameterType.isArray();
+ CtClass arrayType = parameterType.getComponentType();
+ if (isArray) {
+ while (arrayType.isArray()) {
+ arrayType = arrayType.getComponentType();
+ }
+ }
+
+ sb.append(" + \"");
+ try {
+ sb.append(parameterNameFor(method, locals, i));
+ } catch (Exception e) {
+ sb.append("" + (i + 1));
+ }
+ sb.append("\" + \"=");
+
+ if (parameterType.isPrimitive()) {
+ // let the compiler handle primitive -> string
+ sb.append("\"+ $" + (i + 1));
+ } else {
+ String s = "org.slf4j.instrumentation.ToStringHelper.render";
+ sb.append("\"+ " + s + "($" + (i + 1) + ")");
+ }
+ }
+ sb.append("+\")");
+
+ String signature = sb.toString();
+ return signature;
+ }
+
+ /**
+ * Determine the name of parameter with index i in the given method. Use the
+ * locals attributes about local variables from the classfile. Note: This is
+ * still work in progress.
+ *
+ * @param method
+ * @param locals
+ * @param i
+ * @return the name of the parameter if available or a number if not.
+ */
+ static String parameterNameFor(CtBehavior method,
+ LocalVariableAttribute locals, int i) {
+
+ if (locals == null) {
+ return Integer.toString(i + 1);
+ }
+
+ int modifiers = method.getModifiers();
+
+ int j = i;
+
+ if (Modifier.isSynchronized(modifiers)) {
+ // skip object to synchronize upon.
+ j++;
+ // System.err.println("Synchronized");
+ }
+ if (Modifier.isStatic(modifiers) == false) {
+ // skip "this"
+ j++;
+ // System.err.println("Instance");
+ }
+ String variableName = locals.variableName(j);
+ // if (variableName.equals("this")) {
+ // System.err.println("'this' returned as a parameter name for "
+ // + method.getName() + " index " + j
+ // +
+ // ", names are probably shifted. Please submit source for class in slf4j bugreport");
+ // }
+ return variableName;
+ }
}
More information about the slf4j-dev
mailing list