Skip to content

Commit 6cba79b

Browse files
authored
Merge pull request #729 from WillRabalais04/iterate-606
Alternative regex for resolving issue#606
2 parents 7dff2c1 + 757a250 commit 6cba79b

2 files changed

Lines changed: 142 additions & 16 deletions

File tree

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

Lines changed: 41 additions & 16 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,14 @@ 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("^(?<prefix>[^\\[]+)(?<unbounded>(\\[\\])+)(?<bounded>(\\[\\d+\\])+)(?<unneeded>[^\\[]*)$");
59+
5560
protected String type;
5661
protected String name;
5762
protected Value value;
5863
protected List<MutableTreeNode> children = new ArrayList<>();
5964
protected MutableTreeNode parent;
6065

61-
6266
/**
6367
* Construct a {@link VariableNode}.
6468
* @param name the name
@@ -88,25 +92,23 @@ public Value getValue() {
8892
* @return a String representing the value.
8993
*/
9094
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-
} else if (getType() == TYPE_STRING) {
99-
str = ((StringReference) value).value(); // use original string value (without quotes)
100-
} else {
101-
str = value.toString();
102-
}
95+
if (value == null) {
96+
return "null";
97+
}
98+
99+
int typeDescriptor = getType();
100+
if (typeDescriptor == TYPE_OBJECT) {
101+
return "instance of " + type;
102+
} else if (typeDescriptor == TYPE_ARRAY) {
103+
return describeArray(value.toString());
104+
} else if (typeDescriptor == TYPE_STRING) {
105+
// use original string value (without quotes)
106+
return ((StringReference) value).value();
103107
} else {
104-
str = "null";
108+
return value.toString();
105109
}
106-
return str;
107110
}
108111

109-
110112
public String getTypeName() {
111113
return type;
112114
}
@@ -380,4 +382,27 @@ public int hashCode() {
380382
hash = 97 * hash + (this.value != null ? this.value.hashCode() : 0);
381383
return hash;
382384
}
385+
386+
387+
/**
388+
* Describe an array in a human friendly description.
389+
*
390+
* @see Issue #606
391+
* @param fullDescription The full description of the array like "instance of
392+
* int[5] (id=998)" or "instance of int[][5] (id=998)"
393+
* @return Human-friendly description like "instance of int[5]" or
394+
* "instance of int[5][]".
395+
*/
396+
private String describeArray(String fullDescription) {
397+
Matcher matcher = ARRAY_REGEX.matcher(fullDescription);
398+
if (!matcher.matches()) {
399+
return fullDescription;
400+
}
401+
402+
StringJoiner joiner = new StringJoiner("");
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+
}
383408
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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 describeNull() {
15+
VariableNode node = new VariableNode("test", "null", null);
16+
Assert.assertEquals(node.getStringValue(), "null");
17+
}
18+
19+
@Test
20+
public void describeInt() {
21+
Value value = buildMockValue("5");
22+
VariableNode node = new VariableNode("test", "int", value);
23+
Assert.assertEquals(node.getStringValue(), "5");
24+
}
25+
26+
@Test
27+
public void describeFloat() {
28+
Value value = buildMockValue("5.5");
29+
VariableNode node = new VariableNode("test", "float", value);
30+
Assert.assertEquals(node.getStringValue(), "5.5");
31+
}
32+
33+
@Test
34+
public void describeObject() {
35+
Value value = buildMockValue("5.5");
36+
VariableNode node = new VariableNode("test", "Other", value);
37+
Assert.assertEquals(node.getStringValue(), "instance of Other");
38+
}
39+
40+
@Test
41+
public void describeString() {
42+
Value value = buildMockString("testing");
43+
VariableNode node = new VariableNode("test", "java.lang.String", value);
44+
Assert.assertEquals(node.getStringValue(), "testing");
45+
}
46+
47+
@Test
48+
public void describeSimpleArray() {
49+
Value value = buildMockValue("instance of int[5] (id=998)");
50+
VariableNode node = new VariableNode("test", "int[]", value);
51+
Assert.assertEquals(node.getStringValue(), "instance of int[5] (id=998)");
52+
}
53+
54+
@Test
55+
public void describeNestedArraySingleDimensionUnknown() {
56+
Value value = buildMockValue("instance of int[][5] (id=998)");
57+
VariableNode node = new VariableNode("test", "int[][]", value);
58+
Assert.assertEquals(node.getStringValue(), "instance of int[5][]");
59+
}
60+
61+
@Test
62+
public void describeNestedArrayMultiDimensionUnknown() {
63+
Value value = buildMockValue("instance of int[][][5] (id=998)");
64+
VariableNode node = new VariableNode("test", "int[][][]", value);
65+
Assert.assertEquals(node.getStringValue(), "instance of int[5][][]");
66+
}
67+
68+
@Test
69+
public void describeNestedArrayMixed() {
70+
Value value = buildMockValue("instance of int[][][5][7] (id=998)");
71+
VariableNode node = new VariableNode("test", "int[][][][]", value);
72+
Assert.assertEquals(node.getStringValue(), "instance of int[5][7][][]");
73+
}
74+
75+
@Test
76+
public void describeArrayFailsafe() {
77+
Value value = buildMockValue("instance of int[x][7] (id=98)");
78+
VariableNode node = new VariableNode("test", "int[][][][]", value);
79+
Assert.assertEquals(node.getStringValue(), "instance of int[x][7] (id=98)");
80+
}
81+
82+
@Test
83+
public void describeArrayUnexpectedOrder() {
84+
Value value = buildMockValue("instance of int[7][] (id=98)");
85+
VariableNode node = new VariableNode("test", "int[][][][]", value);
86+
Assert.assertEquals(node.getStringValue(), "instance of int[7][] (id=98)");
87+
}
88+
89+
private Value buildMockValue(String toStringValue) {
90+
Value value = Mockito.mock(Value.class);
91+
Mockito.when(value.toString()).thenReturn(toStringValue);
92+
return value;
93+
}
94+
95+
private StringReference buildMockString(String innerValue) {
96+
StringReference value = Mockito.mock(StringReference.class);
97+
Mockito.when(value.value()).thenReturn(innerValue);
98+
return value;
99+
}
100+
101+
}

0 commit comments

Comments
 (0)