Skip to content

Commit 2fdd3e5

Browse files
committed
Refactor to regex and tests.
Closes Debugger lists immediate array dimension last processing#606.
1 parent 5ec4cdc commit 2fdd3e5

File tree

2 files changed

+121
-28
lines changed

2 files changed

+121
-28
lines changed

java/src/processing/mode/java/debug/VariableNode.java

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
import java.util.Collections;
3030
import java.util.Enumeration;
3131
import java.util.List;
32+
import java.util.StringJoiner;
33+
import java.util.regex.Matcher;
34+
import java.util.regex.Pattern;
3235
import javax.swing.tree.MutableTreeNode;
3336
import javax.swing.tree.TreeNode;
3437

@@ -52,13 +55,16 @@ public class VariableNode implements MutableTreeNode {
5255
public static final int TYPE_SHORT = 10;
5356
public static final int TYPE_VOID = 11;
5457

58+
private static final Pattern ARRAY_REGEX = Pattern.compile(
59+
"^(?<prefix>[^\\]]+)(?<unbounded>(\\[\\])*)(?<bounded>(\\[\\d+\\])+).*$"
60+
);
61+
5562
protected String type;
5663
protected String name;
5764
protected Value value;
5865
protected List<MutableTreeNode> children = new ArrayList<>();
5966
protected MutableTreeNode parent;
6067

61-
6268
/**
6369
* Construct a {@link VariableNode}.
6470
* @param name the name
@@ -88,35 +94,21 @@ public Value getValue() {
8894
* @return a String representing the value.
8995
*/
9096
public String getStringValue() {
91-
String str;
92-
if (value != null) {
93-
if (getType() == TYPE_OBJECT) {
94-
str = "instance of " + type;
95-
} else if (getType() == TYPE_ARRAY) {
96-
//instance of int[5] (id=998) --> instance of int[5]
97-
str = value.toString().substring(0, value.toString().lastIndexOf(" "));
98-
/*
99-
*formats multidimensional array values to have the size of the first array in
100-
*the first bracket eg.int[][5]-->int[5][]
101-
*/
102-
// resolves issue #606: https://github.com/processing/processing4/issues/606
103-
if (str.contains("][")) {
104-
String brackets = str.substring(str.indexOf('['));
105-
int arrayDimensions = 0;
106-
String num = brackets.replaceAll("[^\\d]", "");
107-
arrayDimensions = (brackets.length() - num.length()) / 2;
108-
brackets = "[" + num + "]" + "[]".repeat(arrayDimensions - 1);
109-
str = str.substring(0, str.indexOf('[')) + brackets;
110-
}
111-
} else if (getType() == TYPE_STRING) {
112-
str = ((StringReference) value).value(); // use original string value (without quotes)
113-
} else {
114-
str = value.toString();
115-
}
97+
if (value == null) {
98+
return "null";
99+
}
100+
101+
int typeDescriptor = getType();
102+
if (typeDescriptor == TYPE_OBJECT) {
103+
return "instance of " + type;
104+
} else if (typeDescriptor == TYPE_ARRAY) {
105+
return describeArray(value.toString());
106+
} else if (typeDescriptor == TYPE_STRING) {
107+
// use original string value (without quotes)
108+
return ((StringReference) value).value();
116109
} else {
117-
str = "null";
110+
return value.toString();
118111
}
119-
return str;
120112
}
121113

122114

@@ -393,4 +385,24 @@ public int hashCode() {
393385
hash = 97 * hash + (this.value != null ? this.value.hashCode() : 0);
394386
return hash;
395387
}
388+
389+
390+
/**
391+
* Describe an array in a human friendly description.
392+
*
393+
* @see Issue #606
394+
* @param fullDescrition The full description of the array like "instance of
395+
* int[5] (id=998)" or "instance of int[][5] (id=998)"
396+
* @return Human-friendly description like "instance of int[5]" or
397+
* "instance of int[5][]".
398+
*/
399+
private String describeArray(String fullDescription) {
400+
Matcher matcher = ARRAY_REGEX.matcher(fullDescription);
401+
StringJoiner joiner = new StringJoiner("");
402+
System.out.println(matcher.matches());
403+
joiner.add(matcher.group("prefix")); // Type without brackets
404+
joiner.add(matcher.group("bounded")); // Brackets with numbers
405+
joiner.add(matcher.group("unbounded")); // Brackets without numbers
406+
return joiner.toString();
407+
}
396408
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package processing.mode.java.debug;
2+
3+
import com.sun.jdi.StringReference;
4+
import com.sun.jdi.Value;
5+
6+
import org.junit.Assert;
7+
import org.junit.Test;
8+
import org.mockito.Mockito;
9+
10+
11+
public class VariableNodeTests {
12+
13+
@Test
14+
public void describeInt() {
15+
Value value = buildMockValue("5");
16+
VariableNode node = new VariableNode("test", "int", value);
17+
Assert.assertEquals(node.getStringValue(), "5");
18+
}
19+
20+
@Test
21+
public void describeFloat() {
22+
Value value = buildMockValue("5.5");
23+
VariableNode node = new VariableNode("test", "float", value);
24+
Assert.assertEquals(node.getStringValue(), "5.5");
25+
}
26+
27+
@Test
28+
public void describeObject() {
29+
Value value = buildMockValue("5.5");
30+
VariableNode node = new VariableNode("test", "Other", value);
31+
Assert.assertEquals(node.getStringValue(), "instance of Other");
32+
}
33+
34+
@Test
35+
public void describeString() {
36+
Value value = buildMockString("testing");
37+
VariableNode node = new VariableNode("test", "java.lang.String", value);
38+
Assert.assertEquals(node.getStringValue(), "testing");
39+
}
40+
41+
@Test
42+
public void describeSimpleArray() {
43+
Value value = buildMockValue("instance of int[5] (id=998)");
44+
VariableNode node = new VariableNode("test", "int[]", value);
45+
Assert.assertEquals(node.getStringValue(), "instance of int[5]");
46+
}
47+
48+
@Test
49+
public void describeNestedArraySingleDimensionUnknown() {
50+
Value value = buildMockValue("instance of int[][5] (id=998)");
51+
VariableNode node = new VariableNode("test", "int[][]", value);
52+
Assert.assertEquals(node.getStringValue(), "instance of int[5][]");
53+
}
54+
55+
@Test
56+
public void describeNestedArrayMultiDimensionUnknown() {
57+
Value value = buildMockValue("instance of int[][][5] (id=998)");
58+
VariableNode node = new VariableNode("test", "int[][][]", value);
59+
Assert.assertEquals(node.getStringValue(), "instance of int[5][][]");
60+
}
61+
62+
@Test
63+
public void describeNestedArrayMixed() {
64+
Value value = buildMockValue("instance of int[][][5][7] (id=998)");
65+
VariableNode node = new VariableNode("test", "int[][][][]", value);
66+
Assert.assertEquals(node.getStringValue(), "instance of int[5][7][][]");
67+
}
68+
69+
private Value buildMockValue(String toStringValue) {
70+
Value value = Mockito.mock(Value.class);
71+
Mockito.when(value.toString()).thenReturn(toStringValue);
72+
return value;
73+
}
74+
75+
private StringReference buildMockString(String innerValue) {
76+
StringReference value = Mockito.mock(StringReference.class);
77+
Mockito.when(value.value()).thenReturn(innerValue);
78+
return value;
79+
}
80+
81+
}

0 commit comments

Comments
 (0)