Skip to content

Commit aadafc2

Browse files
author
Jason Feinstein
committed
Add help; command to the SQLite REPL.
1 parent b11b83f commit aadafc2

18 files changed

+317
-168
lines changed

library/src/main/java/jwf/debugport/annotations/Command.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@
1414
String GROUP_METHOD_INSPECTION = "Method Inspection";
1515
String GROUP_FIELD_INSPECTION = "Field Inspection";
1616
String GROUP_ACCESS = "Access";
17+
String GROUP_SQL_INSPECTION = "Inspection";
18+
String GROUP_SQL_DATABASES = "Databases";
1719
String GROUP_OTHER = "Other";
1820

1921
String group() default GROUP_OTHER;
2022

21-
@Target(ElementType.METHOD)
23+
@Target({ElementType.METHOD, ElementType.TYPE})
2224
@Retention(RetentionPolicy.RUNTIME)
2325
@interface Help {
2426
String value() default "";
27+
String group() default GROUP_OTHER;
28+
String format() default "";
2529
}
2630

2731
@Target(ElementType.PARAMETER)
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package jwf.debugport.internal;
2+
3+
import android.text.TextUtils;
4+
5+
import java.lang.annotation.Annotation;
6+
import java.lang.reflect.Method;
7+
import java.util.StringTokenizer;
8+
9+
import jwf.debugport.annotations.Command;
10+
11+
/**
12+
* Created by jason on 5/15/16.
13+
*/
14+
public class CommandHelpInfo implements Comparable<CommandHelpInfo> {
15+
private final Class mCommandClass;
16+
private Command.Help mHelpAnnotation;
17+
private Command mCommandAnnotation;
18+
19+
public CommandHelpInfo(Class commandClass) {
20+
mCommandClass = commandClass;
21+
if (commandClass.isAnnotationPresent(Command.class)) {
22+
mCommandAnnotation = (Command) commandClass.getAnnotation(Command.class);
23+
}
24+
if (commandClass.isAnnotationPresent(Command.Help.class)) {
25+
mHelpAnnotation = (Command.Help) commandClass.getAnnotation(Command.Help.class);
26+
}
27+
}
28+
29+
public String getCommandGroup() {
30+
if (mHelpAnnotation != null && !TextUtils.isEmpty(mHelpAnnotation.group())) {
31+
return mHelpAnnotation.group();
32+
}
33+
if (mCommandAnnotation != null && !TextUtils.isEmpty(mCommandAnnotation.group())) {
34+
return mCommandAnnotation.group();
35+
}
36+
return Command.GROUP_OTHER;
37+
}
38+
39+
public void appendHelpInfoForMethods(StringBuilder target, int nameStartCol, int helpStartCol, int maxCols) {
40+
Method[] methods = mCommandClass.getMethods();
41+
boolean isFirst = true;
42+
for (Method method : methods) {
43+
if (!method.getName().equals("invoke") || !method.isAnnotationPresent(Command.Help.class)) {
44+
continue;
45+
}
46+
47+
// separate each item with a new line.
48+
if (!isFirst) {
49+
target.append("\n");
50+
}
51+
isFirst = false;
52+
53+
target.append(Utils.spaces(nameStartCol));
54+
String signature = getSignature(method);
55+
target.append(signature);
56+
target.append("\n");
57+
58+
appendHelpText(target, method.getAnnotation(Command.Help.class).value(), helpStartCol, maxCols);
59+
}
60+
}
61+
62+
public void appendHelpInfoForClass(StringBuilder target, int nameStartCol, int helpStartCol, int maxCols) {
63+
target.append(Utils.spaces(nameStartCol));
64+
if (!TextUtils.isEmpty(mHelpAnnotation.format())) {
65+
target.append(mHelpAnnotation.format());
66+
} else {
67+
target.append(mCommandClass.getSimpleName());
68+
}
69+
target.append("\n");
70+
appendHelpText(target, mHelpAnnotation.value(), helpStartCol, maxCols);
71+
}
72+
73+
String getSignature(Method method) {
74+
Annotation[][] paramAnnotations = method.getParameterAnnotations();
75+
Class<?>[] params = method.getParameterTypes();
76+
StringBuilder signatureBuilder = new StringBuilder();
77+
signatureBuilder.append(mCommandClass.getSimpleName());
78+
signatureBuilder.append("(");
79+
for (int j = 2; j < params.length; j++) {
80+
// first two params are Interpreter and CallStack, ignore those.
81+
if (j != 2) {
82+
signatureBuilder.append(", ");
83+
}
84+
85+
String name = params[j].getSimpleName();
86+
if (j == params.length - 1 && method.isVarArgs() && params[j].isArray()) {
87+
signatureBuilder.append(name.replace("[]", ""));
88+
signatureBuilder.append("...");
89+
} else {
90+
signatureBuilder.append(name);
91+
}
92+
93+
Annotation[] annotations = paramAnnotations[j];
94+
Command.ParamName paramAnnotation = null;
95+
for (Annotation a : annotations) {
96+
if (a instanceof Command.ParamName) {
97+
paramAnnotation = (Command.ParamName) a;
98+
break;
99+
}
100+
}
101+
if (paramAnnotation != null) {
102+
if (!TextUtils.isEmpty(paramAnnotation.value())) {
103+
signatureBuilder.append(" ");
104+
signatureBuilder.append(paramAnnotation.value());
105+
}
106+
}
107+
}
108+
signatureBuilder.append(")");
109+
return signatureBuilder.toString();
110+
}
111+
112+
public static void appendHelpText(StringBuilder target, String helpText, int helpStartCol, int maxCols) {
113+
int cols = helpStartCol;
114+
target.append(Utils.spaces(helpStartCol));
115+
116+
StringTokenizer tokens = new StringTokenizer(helpText, " ");
117+
while (tokens.hasMoreTokens()) {
118+
String token = tokens.nextToken();
119+
target.append(token);
120+
if (tokens.hasMoreTokens()) {
121+
target.append(" ");
122+
}
123+
cols += token.length() + 1;
124+
if (cols >= maxCols && tokens.hasMoreTokens()) {
125+
cols = helpStartCol;
126+
target.append("\n");
127+
target.append(Utils.spaces(helpStartCol));
128+
}
129+
}
130+
}
131+
132+
@SuppressWarnings("NullableProblems")
133+
@Override
134+
public int compareTo(CommandHelpInfo another) {
135+
if (another == null) {
136+
return -1;
137+
}
138+
String myGroup = getCommandGroup();
139+
String theirGroup = another.getCommandGroup();
140+
int groupCompare = myGroup.compareTo(theirGroup);
141+
if (groupCompare != 0) {
142+
// "Other" group should always come last.
143+
if (myGroup.equals(Command.GROUP_OTHER)) {
144+
return 1;
145+
}
146+
if (theirGroup.equals(Command.GROUP_OTHER)) {
147+
return - 1;
148+
}
149+
return groupCompare;
150+
}
151+
return mCommandClass.getSimpleName().compareTo(another.mCommandClass.getSimpleName());
152+
}
153+
154+
public Class getCommandClass() {
155+
return mCommandClass;
156+
}
157+
}

library/src/main/java/jwf/debugport/internal/Utils.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
*
1414
*/
1515
public class Utils {
16+
public static final int INDENT_SPACES = 2;
17+
1618
@SuppressLint("DefaultLocale")
1719
public static String getIpAddress(Context context) {
1820
WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@@ -121,4 +123,12 @@ public static String nanosToMillis(long nanos) {
121123
float millis = nanos / 1000000.0f;
122124
return String.format(Locale.getDefault(), "%.3fms", millis);
123125
}
126+
127+
public static String spaces(int spaces) {
128+
return multStr(" ", spaces);
129+
}
130+
131+
public static String indent(int indentations) {
132+
return spaces(indentations * INDENT_SPACES);
133+
}
124134
}

library/src/main/java/jwf/debugport/internal/debug/commands/CommandUtils.java

Lines changed: 0 additions & 20 deletions
This file was deleted.

library/src/main/java/jwf/debugport/internal/debug/commands/fields.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import bsh.CallStack;
44
import bsh.Interpreter;
55
import jwf.debugport.annotations.Command;
6+
import jwf.debugport.internal.Utils;
67
import jwf.debugport.internal.debug.commands.descriptors.FieldDescriptor;
78

89
/**
@@ -27,7 +28,7 @@ public static void invoke(Interpreter interpreter, CallStack callStack, @Command
2728
sb.append("fields {\n");
2829

2930
for (FieldDescriptor field : fields) {
30-
sb.append(CommandUtils.indent(1));
31+
sb.append(Utils.indent(1));
3132
sb.append(field.toString());
3233
sb.append("\n");
3334
}

library/src/main/java/jwf/debugport/internal/debug/commands/fieldsLocal.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import bsh.CallStack;
44
import bsh.Interpreter;
55
import jwf.debugport.annotations.Command;
6+
import jwf.debugport.internal.Utils;
67
import jwf.debugport.internal.debug.commands.descriptors.FieldDescriptor;
78

89
/**
@@ -27,7 +28,7 @@ public static void invoke(Interpreter interpreter, CallStack callStack, @Command
2728
sb.append("declared fields {\n");
2829

2930
for (FieldDescriptor field : fields) {
30-
sb.append(CommandUtils.indent(1));
31+
sb.append(Utils.indent(1));
3132
sb.append(field.toString());
3233
sb.append("\n");
3334
}

0 commit comments

Comments
 (0)