From 9489ad8b3350ee2ce445dd0d4f11cea86fcd11f5 Mon Sep 17 00:00:00 2001 From: WillRabalais04 <69363495+WillRabalais04@users.noreply.github.com> Date: Fri, 24 Mar 2023 01:47:55 -0400 Subject: [PATCH 01/16] Bugfix for Issue #606 Updates the getStringValue method of the VariableNode class so that it correctly handles multidimensional arrays. The default formatting of multidimensional arrays is to have the size of the first array written in the last set of brackets eg.int[][5]. This changes it so that the returned value has the size of the first array written in the first set of brackets eg.int[5][]. This can parse multidimensional arrays of any size. --- .../processing/mode/java/debug/VariableNode.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/java/src/processing/mode/java/debug/VariableNode.java b/java/src/processing/mode/java/debug/VariableNode.java index b8b2684471..fb3df50027 100644 --- a/java/src/processing/mode/java/debug/VariableNode.java +++ b/java/src/processing/mode/java/debug/VariableNode.java @@ -95,6 +95,19 @@ public String getStringValue() { } else if (getType() == TYPE_ARRAY) { //instance of int[5] (id=998) --> instance of int[5] str = value.toString().substring(0, value.toString().lastIndexOf(" ")); + /* + *formats multidimensional array values to have the size of the first array in + *the first bracket eg.int[][5]-->int[5][] + */ + // resolves issue #606: https://github.com/processing/processing4/issues/606 + if (str.contains("][")) { + String brackets = str.substring(str.indexOf('[')); + int arrayDimensions = 0; + String num = brackets.replaceAll("[^\\d]", ""); + arrayDimensions = (brackets.length() - num.length()) / 2; + brackets = "[" + num + "]" + "[]".repeat(arrayDimensions - 1); + str = str.substring(0, str.indexOf('[')) + brackets; + } } else if (getType() == TYPE_STRING) { str = ((StringReference) value).value(); // use original string value (without quotes) } else { From 2fdd3e5f362f17241ff698ffed7eda2a902b3393 Mon Sep 17 00:00:00 2001 From: A Samuel Pottinger Date: Tue, 9 May 2023 18:12:27 +0000 Subject: [PATCH 02/16] Refactor to regex and tests. Closes Debugger lists immediate array dimension last #606. --- .../mode/java/debug/VariableNode.java | 68 +++++++++------- .../mode/java/debug/VariableNodeTests.java | 81 +++++++++++++++++++ 2 files changed, 121 insertions(+), 28 deletions(-) create mode 100644 java/test/processing/mode/java/debug/VariableNodeTests.java diff --git a/java/src/processing/mode/java/debug/VariableNode.java b/java/src/processing/mode/java/debug/VariableNode.java index fb3df50027..57a60a00ca 100644 --- a/java/src/processing/mode/java/debug/VariableNode.java +++ b/java/src/processing/mode/java/debug/VariableNode.java @@ -29,6 +29,9 @@ import java.util.Collections; import java.util.Enumeration; import java.util.List; +import java.util.StringJoiner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeNode; @@ -52,13 +55,16 @@ public class VariableNode implements MutableTreeNode { public static final int TYPE_SHORT = 10; public static final int TYPE_VOID = 11; + private static final Pattern ARRAY_REGEX = Pattern.compile( + "^(?[^\\]]+)(?(\\[\\])*)(?(\\[\\d+\\])+).*$" + ); + protected String type; protected String name; protected Value value; protected List children = new ArrayList<>(); protected MutableTreeNode parent; - /** * Construct a {@link VariableNode}. * @param name the name @@ -88,35 +94,21 @@ public Value getValue() { * @return a String representing the value. */ public String getStringValue() { - String str; - if (value != null) { - if (getType() == TYPE_OBJECT) { - str = "instance of " + type; - } else if (getType() == TYPE_ARRAY) { - //instance of int[5] (id=998) --> instance of int[5] - str = value.toString().substring(0, value.toString().lastIndexOf(" ")); - /* - *formats multidimensional array values to have the size of the first array in - *the first bracket eg.int[][5]-->int[5][] - */ - // resolves issue #606: https://github.com/processing/processing4/issues/606 - if (str.contains("][")) { - String brackets = str.substring(str.indexOf('[')); - int arrayDimensions = 0; - String num = brackets.replaceAll("[^\\d]", ""); - arrayDimensions = (brackets.length() - num.length()) / 2; - brackets = "[" + num + "]" + "[]".repeat(arrayDimensions - 1); - str = str.substring(0, str.indexOf('[')) + brackets; - } - } else if (getType() == TYPE_STRING) { - str = ((StringReference) value).value(); // use original string value (without quotes) - } else { - str = value.toString(); - } + if (value == null) { + return "null"; + } + + int typeDescriptor = getType(); + if (typeDescriptor == TYPE_OBJECT) { + return "instance of " + type; + } else if (typeDescriptor == TYPE_ARRAY) { + return describeArray(value.toString()); + } else if (typeDescriptor == TYPE_STRING) { + // use original string value (without quotes) + return ((StringReference) value).value(); } else { - str = "null"; + return value.toString(); } - return str; } @@ -393,4 +385,24 @@ public int hashCode() { hash = 97 * hash + (this.value != null ? this.value.hashCode() : 0); return hash; } + + + /** + * Describe an array in a human friendly description. + * + * @see Issue #606 + * @param fullDescrition The full description of the array like "instance of + * int[5] (id=998)" or "instance of int[][5] (id=998)" + * @return Human-friendly description like "instance of int[5]" or + * "instance of int[5][]". + */ + private String describeArray(String fullDescription) { + Matcher matcher = ARRAY_REGEX.matcher(fullDescription); + StringJoiner joiner = new StringJoiner(""); + System.out.println(matcher.matches()); + joiner.add(matcher.group("prefix")); // Type without brackets + joiner.add(matcher.group("bounded")); // Brackets with numbers + joiner.add(matcher.group("unbounded")); // Brackets without numbers + return joiner.toString(); + } } diff --git a/java/test/processing/mode/java/debug/VariableNodeTests.java b/java/test/processing/mode/java/debug/VariableNodeTests.java new file mode 100644 index 0000000000..fb03d24326 --- /dev/null +++ b/java/test/processing/mode/java/debug/VariableNodeTests.java @@ -0,0 +1,81 @@ +package processing.mode.java.debug; + +import com.sun.jdi.StringReference; +import com.sun.jdi.Value; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + + +public class VariableNodeTests { + + @Test + public void describeInt() { + Value value = buildMockValue("5"); + VariableNode node = new VariableNode("test", "int", value); + Assert.assertEquals(node.getStringValue(), "5"); + } + + @Test + public void describeFloat() { + Value value = buildMockValue("5.5"); + VariableNode node = new VariableNode("test", "float", value); + Assert.assertEquals(node.getStringValue(), "5.5"); + } + + @Test + public void describeObject() { + Value value = buildMockValue("5.5"); + VariableNode node = new VariableNode("test", "Other", value); + Assert.assertEquals(node.getStringValue(), "instance of Other"); + } + + @Test + public void describeString() { + Value value = buildMockString("testing"); + VariableNode node = new VariableNode("test", "java.lang.String", value); + Assert.assertEquals(node.getStringValue(), "testing"); + } + + @Test + public void describeSimpleArray() { + Value value = buildMockValue("instance of int[5] (id=998)"); + VariableNode node = new VariableNode("test", "int[]", value); + Assert.assertEquals(node.getStringValue(), "instance of int[5]"); + } + + @Test + public void describeNestedArraySingleDimensionUnknown() { + Value value = buildMockValue("instance of int[][5] (id=998)"); + VariableNode node = new VariableNode("test", "int[][]", value); + Assert.assertEquals(node.getStringValue(), "instance of int[5][]"); + } + + @Test + public void describeNestedArrayMultiDimensionUnknown() { + Value value = buildMockValue("instance of int[][][5] (id=998)"); + VariableNode node = new VariableNode("test", "int[][][]", value); + Assert.assertEquals(node.getStringValue(), "instance of int[5][][]"); + } + + @Test + public void describeNestedArrayMixed() { + Value value = buildMockValue("instance of int[][][5][7] (id=998)"); + VariableNode node = new VariableNode("test", "int[][][][]", value); + Assert.assertEquals(node.getStringValue(), "instance of int[5][7][][]"); + } + + private Value buildMockValue(String toStringValue) { + Value value = Mockito.mock(Value.class); + Mockito.when(value.toString()).thenReturn(toStringValue); + return value; + } + + private StringReference buildMockString(String innerValue) { + StringReference value = Mockito.mock(StringReference.class); + Mockito.when(value.value()).thenReturn(innerValue); + return value; + } + +} From cd313c61389b9703000bbd483668290f611c7ddd Mon Sep 17 00:00:00 2001 From: A Samuel Pottinger Date: Tue, 9 May 2023 18:26:15 +0000 Subject: [PATCH 03/16] Add test to describe null on #713. --- java/test/processing/mode/java/debug/VariableNodeTests.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/test/processing/mode/java/debug/VariableNodeTests.java b/java/test/processing/mode/java/debug/VariableNodeTests.java index fb03d24326..f8763b9343 100644 --- a/java/test/processing/mode/java/debug/VariableNodeTests.java +++ b/java/test/processing/mode/java/debug/VariableNodeTests.java @@ -10,6 +10,12 @@ public class VariableNodeTests { + @Test + public void describeNull() { + VariableNode node = new VariableNode("test", "null", null); + Assert.assertEquals(node.getStringValue(), "null"); + } + @Test public void describeInt() { Value value = buildMockValue("5"); From 5c3fa69f57980ac94410882bb9e765aa53b9981f Mon Sep 17 00:00:00 2001 From: A Samuel Pottinger Date: Tue, 9 May 2023 18:37:08 +0000 Subject: [PATCH 04/16] Add failsafe for #713. --- java/src/processing/mode/java/debug/VariableNode.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/src/processing/mode/java/debug/VariableNode.java b/java/src/processing/mode/java/debug/VariableNode.java index 57a60a00ca..9b8c418dee 100644 --- a/java/src/processing/mode/java/debug/VariableNode.java +++ b/java/src/processing/mode/java/debug/VariableNode.java @@ -399,7 +399,10 @@ public int hashCode() { private String describeArray(String fullDescription) { Matcher matcher = ARRAY_REGEX.matcher(fullDescription); StringJoiner joiner = new StringJoiner(""); - System.out.println(matcher.matches()); + if (!matcher.matches()) { + return fullDescription; + } + joiner.add(matcher.group("prefix")); // Type without brackets joiner.add(matcher.group("bounded")); // Brackets with numbers joiner.add(matcher.group("unbounded")); // Brackets without numbers From 674cfe0766e3769f8bac86b845a927e3748a4f91 Mon Sep 17 00:00:00 2001 From: A Samuel Pottinger Date: Tue, 9 May 2023 18:41:36 +0000 Subject: [PATCH 05/16] Add test for failsafe. --- .../test/processing/mode/java/debug/VariableNodeTests.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/java/test/processing/mode/java/debug/VariableNodeTests.java b/java/test/processing/mode/java/debug/VariableNodeTests.java index f8763b9343..9b5530ffde 100644 --- a/java/test/processing/mode/java/debug/VariableNodeTests.java +++ b/java/test/processing/mode/java/debug/VariableNodeTests.java @@ -72,6 +72,13 @@ public void describeNestedArrayMixed() { Assert.assertEquals(node.getStringValue(), "instance of int[5][7][][]"); } + @Test + public void describeArrayFailsafe() { + Value value = buildMockValue("instance of int[x][7] (id=998)"); + VariableNode node = new VariableNode("test", "int[][][][]", value); + Assert.assertEquals(node.getStringValue(), "instance of int[x][7] (id=998)); + } + private Value buildMockValue(String toStringValue) { Value value = Mockito.mock(Value.class); Mockito.when(value.toString()).thenReturn(toStringValue); From 0987f67fc9add3b8609f11acb8d0df218bf30c66 Mon Sep 17 00:00:00 2001 From: A Samuel Pottinger Date: Wed, 10 May 2023 14:01:46 +0000 Subject: [PATCH 06/16] Clarify unneeded section. --- java/src/processing/mode/java/debug/VariableNode.java | 2 +- .../processing/mode/java/debug/VariableNodeTests.java | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/java/src/processing/mode/java/debug/VariableNode.java b/java/src/processing/mode/java/debug/VariableNode.java index 9b8c418dee..7056854b2d 100644 --- a/java/src/processing/mode/java/debug/VariableNode.java +++ b/java/src/processing/mode/java/debug/VariableNode.java @@ -56,7 +56,7 @@ public class VariableNode implements MutableTreeNode { public static final int TYPE_VOID = 11; private static final Pattern ARRAY_REGEX = Pattern.compile( - "^(?[^\\]]+)(?(\\[\\])*)(?(\\[\\d+\\])+).*$" + "^(?[^\\[]+)(?(\\[\\])*)(?(\\[\\d+\\])+)(?[^\\[]*)$" ); protected String type; diff --git a/java/test/processing/mode/java/debug/VariableNodeTests.java b/java/test/processing/mode/java/debug/VariableNodeTests.java index 9b5530ffde..427f902150 100644 --- a/java/test/processing/mode/java/debug/VariableNodeTests.java +++ b/java/test/processing/mode/java/debug/VariableNodeTests.java @@ -74,9 +74,16 @@ public void describeNestedArrayMixed() { @Test public void describeArrayFailsafe() { - Value value = buildMockValue("instance of int[x][7] (id=998)"); + Value value = buildMockValue("instance of int[x][7] (id=98)"); VariableNode node = new VariableNode("test", "int[][][][]", value); - Assert.assertEquals(node.getStringValue(), "instance of int[x][7] (id=998)); + Assert.assertEquals(node.getStringValue(), "instance of int[x][7] (id=98)"); + } + + @Test + public void describeArrayUnexpectedOrder() { + Value value = buildMockValue("instance of int[7][] (id=98)"); + VariableNode node = new VariableNode("test", "int[][][][]", value); + Assert.assertEquals(node.getStringValue(), "instance of int[7][] (id=98)"); } private Value buildMockValue(String toStringValue) { From 490fc2bfee426ef6fd890f6944579f4f33b7d54f Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Wed, 10 May 2023 16:13:37 -0700 Subject: [PATCH 07/16] Closes #714. Depending on how the Problem is made, the error may be given relative to start of line or start of tab. Flag indicates to users of Problems which one they are working with. --- app/src/processing/app/Problem.java | 2 +- .../processing/app/syntax/PdeTextAreaPainter.java | 5 +++++ app/src/processing/app/ui/Editor.java | 10 +++++++++- java/src/processing/mode/java/JavaProblem.java | 5 ++++- java/src/processing/mode/java/ProblemFactory.java | 8 +++++--- java/src/processing/mode/java/SyntaxProblem.java | 14 +++++++++++--- 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/Problem.java b/app/src/processing/app/Problem.java index cb12ad5e3e..e271836c95 100644 --- a/app/src/processing/app/Problem.java +++ b/app/src/processing/app/Problem.java @@ -17,7 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - package processing.app; @@ -29,6 +28,7 @@ public interface Problem { public int getLineNumber(); // 0-indexed public String getMessage(); + public boolean isLineOffset(); public int getStartOffset(); public int getStopOffset(); } diff --git a/app/src/processing/app/syntax/PdeTextAreaPainter.java b/app/src/processing/app/syntax/PdeTextAreaPainter.java index ef517a9d24..8b3fb37d82 100644 --- a/app/src/processing/app/syntax/PdeTextAreaPainter.java +++ b/app/src/processing/app/syntax/PdeTextAreaPainter.java @@ -152,6 +152,11 @@ protected void paintErrorLine(Graphics gfx, int line, int x) { int lineOffset = textArea.getLineStartOffset(line); + if (problem.isLineOffset()) { + startOffset += lineOffset; + stopOffset += lineOffset; + } + int wiggleStart = Math.max(startOffset, lineOffset); int wiggleStop = Math.min(stopOffset, textArea.getLineStopOffset(line)); diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index b9761aa79e..77f1bb7b12 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2624,7 +2624,15 @@ public List findProblems(int line) { .filter(p -> { int pStartLine = p.getLineNumber(); int pEndOffset = p.getStopOffset(); - int pEndLine = textarea.getLineOfOffset(pEndOffset); + + int pEndLine; + if (p.isLineOffset()) { + int lineGlobalOffset = textarea.getLineStartOffset(pStartLine); + pEndLine = textarea.getLineOfOffset(pEndOffset + lineGlobalOffset); + } else { + pEndLine = textarea.getLineOfOffset(pEndOffset); + } + return line >= pStartLine && line <= pEndLine; }) .collect(Collectors.toList()); diff --git a/java/src/processing/mode/java/JavaProblem.java b/java/src/processing/mode/java/JavaProblem.java index 232063d2f0..687926085a 100644 --- a/java/src/processing/mode/java/JavaProblem.java +++ b/java/src/processing/mode/java/JavaProblem.java @@ -82,7 +82,7 @@ static public JavaProblem fromIProblem(IProblem iProblem, int tabIndex, } - public void setPDEOffsets(int startOffset, int stopOffset){ + public void setPDEOffsets(int startOffset, int stopOffset) { this.startOffset = startOffset; this.stopOffset = stopOffset; } @@ -139,6 +139,9 @@ public void setImportSuggestions(String[] a) { importSuggestions = a; } + public boolean isLineOffset() { + return false; + } @Override public String toString() { diff --git a/java/src/processing/mode/java/ProblemFactory.java b/java/src/processing/mode/java/ProblemFactory.java index e7ec067296..ce5cbff63a 100644 --- a/java/src/processing/mode/java/ProblemFactory.java +++ b/java/src/processing/mode/java/ProblemFactory.java @@ -53,7 +53,8 @@ public static Problem build(PdePreprocessIssue pdePreprocessIssue, List localLine, message, lineStart, - lineStop + lineStop, + false ); } @@ -83,8 +84,9 @@ public static Problem build(PdePreprocessIssue pdePreprocessIssue, List tab, localLine, message, - localLine, - localLine + col + 0, + col, + true ); } diff --git a/java/src/processing/mode/java/SyntaxProblem.java b/java/src/processing/mode/java/SyntaxProblem.java index 14b9e92620..b0f8d97dff 100644 --- a/java/src/processing/mode/java/SyntaxProblem.java +++ b/java/src/processing/mode/java/SyntaxProblem.java @@ -10,6 +10,7 @@ public class SyntaxProblem extends JavaProblem { private final String message; private final int startOffset; private final int stopOffset; + private final boolean lineFlag; /** * Create a new syntax problem. @@ -18,12 +19,14 @@ public class SyntaxProblem extends JavaProblem { * @param newLineNumber The line number within the tab at which the offending code can be found. * @param newMessage Human readable message describing the issue. * @param newStartOffset The character index at which the issue starts. This is relative to start - * of tab / file not relative to start of line. + * of tab / file not relative to start of line if newIsLineOffset is true else it is line + * offset. * @param newStopOffset The character index at which the issue ends. This is relative to start - * * of tab / file not relative to start of line. + * of tab / file not relative to start of line if newIsLineOffset is true else it is line + * offset. */ public SyntaxProblem(int newTabIndex, int newLineNumber, String newMessage, int newStartOffset, - int newStopOffset) { + int newStopOffset, boolean newIsLineOffset) { super(newMessage, JavaProblem.ERROR, newLineNumber, newLineNumber); @@ -32,6 +35,7 @@ public SyntaxProblem(int newTabIndex, int newLineNumber, String newMessage, int message = newMessage; startOffset = newStartOffset; stopOffset = newStopOffset; + lineFlag = newIsLineOffset; } @Override @@ -69,4 +73,8 @@ public int getStopOffset() { return stopOffset; } + public boolean isLineOffset() { + return lineFlag; + } + } From 761db14d99ed5c7f8f584739c1ce066e5b997b7b Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Wed, 10 May 2023 16:17:08 -0700 Subject: [PATCH 08/16] Reverse accidential change related to #715. --- java/src/processing/mode/java/JavaProblem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/processing/mode/java/JavaProblem.java b/java/src/processing/mode/java/JavaProblem.java index 687926085a..4b9553cd7d 100644 --- a/java/src/processing/mode/java/JavaProblem.java +++ b/java/src/processing/mode/java/JavaProblem.java @@ -82,7 +82,7 @@ static public JavaProblem fromIProblem(IProblem iProblem, int tabIndex, } - public void setPDEOffsets(int startOffset, int stopOffset) { + public void setPDEOffsets(int startOffset, int stopOffset){ this.startOffset = startOffset; this.stopOffset = stopOffset; } From e69ad56b09801d2dda5d081576e9101c8537b90c Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Wed, 10 May 2023 16:19:57 -0700 Subject: [PATCH 09/16] Style fixes related to #715. --- app/src/processing/app/Problem.java | 2 +- app/src/processing/app/syntax/PdeTextAreaPainter.java | 2 +- app/src/processing/app/ui/Editor.java | 2 +- java/src/processing/mode/java/JavaProblem.java | 2 +- java/src/processing/mode/java/SyntaxProblem.java | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/Problem.java b/app/src/processing/app/Problem.java index e271836c95..d087e7bb45 100644 --- a/app/src/processing/app/Problem.java +++ b/app/src/processing/app/Problem.java @@ -28,7 +28,7 @@ public interface Problem { public int getLineNumber(); // 0-indexed public String getMessage(); - public boolean isLineOffset(); + public boolean usesLineOffset(); public int getStartOffset(); public int getStopOffset(); } diff --git a/app/src/processing/app/syntax/PdeTextAreaPainter.java b/app/src/processing/app/syntax/PdeTextAreaPainter.java index 8b3fb37d82..e55fa413c2 100644 --- a/app/src/processing/app/syntax/PdeTextAreaPainter.java +++ b/app/src/processing/app/syntax/PdeTextAreaPainter.java @@ -152,7 +152,7 @@ protected void paintErrorLine(Graphics gfx, int line, int x) { int lineOffset = textArea.getLineStartOffset(line); - if (problem.isLineOffset()) { + if (problem.usesLineOffset()) { startOffset += lineOffset; stopOffset += lineOffset; } diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 77f1bb7b12..3cf6d7ba1d 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2626,7 +2626,7 @@ public List findProblems(int line) { int pEndOffset = p.getStopOffset(); int pEndLine; - if (p.isLineOffset()) { + if (p.usesLineOffset()) { int lineGlobalOffset = textarea.getLineStartOffset(pStartLine); pEndLine = textarea.getLineOfOffset(pEndOffset + lineGlobalOffset); } else { diff --git a/java/src/processing/mode/java/JavaProblem.java b/java/src/processing/mode/java/JavaProblem.java index 4b9553cd7d..adf86fcab7 100644 --- a/java/src/processing/mode/java/JavaProblem.java +++ b/java/src/processing/mode/java/JavaProblem.java @@ -139,7 +139,7 @@ public void setImportSuggestions(String[] a) { importSuggestions = a; } - public boolean isLineOffset() { + public boolean usesLineOffset() { return false; } diff --git a/java/src/processing/mode/java/SyntaxProblem.java b/java/src/processing/mode/java/SyntaxProblem.java index b0f8d97dff..a1af0ed8b2 100644 --- a/java/src/processing/mode/java/SyntaxProblem.java +++ b/java/src/processing/mode/java/SyntaxProblem.java @@ -19,14 +19,14 @@ public class SyntaxProblem extends JavaProblem { * @param newLineNumber The line number within the tab at which the offending code can be found. * @param newMessage Human readable message describing the issue. * @param newStartOffset The character index at which the issue starts. This is relative to start - * of tab / file not relative to start of line if newIsLineOffset is true else it is line + * of tab / file not relative to start of line if newUsesLineOffset is true else it is line * offset. * @param newStopOffset The character index at which the issue ends. This is relative to start - * of tab / file not relative to start of line if newIsLineOffset is true else it is line + * of tab / file not relative to start of line if newUsesLineOffset is true else it is line * offset. */ public SyntaxProblem(int newTabIndex, int newLineNumber, String newMessage, int newStartOffset, - int newStopOffset, boolean newIsLineOffset) { + int newStopOffset, boolean newUsesLineOffset) { super(newMessage, JavaProblem.ERROR, newLineNumber, newLineNumber); @@ -35,7 +35,7 @@ public SyntaxProblem(int newTabIndex, int newLineNumber, String newMessage, int message = newMessage; startOffset = newStartOffset; stopOffset = newStopOffset; - lineFlag = newIsLineOffset; + lineFlag = newUsesLineOffset; } @Override @@ -73,7 +73,7 @@ public int getStopOffset() { return stopOffset; } - public boolean isLineOffset() { + public boolean usesLineOffset() { return lineFlag; } From 4039cb7a6af6d69fdc67aee623d06e7810789440 Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Wed, 10 May 2023 16:20:19 -0700 Subject: [PATCH 10/16] Reverse accidential change for #715. --- app/src/processing/app/Problem.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/processing/app/Problem.java b/app/src/processing/app/Problem.java index d087e7bb45..ab4412ed99 100644 --- a/app/src/processing/app/Problem.java +++ b/app/src/processing/app/Problem.java @@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + package processing.app; From a0cbb64b4dc43a1b333b752588c78109607519aa Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Wed, 10 May 2023 16:33:18 -0700 Subject: [PATCH 11/16] Add docstring to Problem. --- app/src/processing/app/Problem.java | 62 ++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/Problem.java b/app/src/processing/app/Problem.java index ab4412ed99..2e69c8dd1a 100644 --- a/app/src/processing/app/Problem.java +++ b/app/src/processing/app/Problem.java @@ -21,16 +21,76 @@ package processing.app; +/** + * Structure describing a problem encountered in sketch compilation. + */ public interface Problem { + + /** + * Get if the problem is an error that prevented compilation. + * + * @return True if an error such that the sketch did not compile and false + * otherwise. + */ public boolean isError(); + + /** + * Get if the problem is an warning that did not prevent compilation. + * + * @return True if a warning and the sketch compiled and false otherwise. + */ public boolean isWarning(); + /** + * Get which tab (sketch file) the problem was encountered. + * + * @return The index of the tab in which the problem was encountered. + */ public int getTabIndex(); - public int getLineNumber(); // 0-indexed + + /** + * Get at which line the problem was encountered. + * + * @return Zero-indexed line number within the tab at getTabIndex in which + * this problem was encountered. Note that this is not the line in the + * generated Java file. + */ + public int getLineNumber(); + + /** + * Get a human-reabable description of the problem encountered. + * + * @return String describing the error or warning encountered. + */ public String getMessage(); + /** + * Determine against what reference point for the this Problem's specific + * location is reported. + * + * @return True if getStartOffset and getStopOffset are number of characters + * relative to the start of the line reported by getLineNumber. False if + * getStartOffset and getStopOffset are number of characters from start of + * the tab. + */ public boolean usesLineOffset(); + + /** + * Get the exact character on which this problem starts in code. + * + * @return Number of characters past the reference point in usesLineOffset + * at which this problem starts (where the code to which the problem + * is attributed starts). + */ public int getStartOffset(); + + /** + * Get the exact character on which this problem ends in code. + * + * @return Number of characters past the reference point in usesLineOffset + * at which this problem ends (where the code to which the problem + * is attributed ends). + */ public int getStopOffset(); } From 9fcf7527aabf0badff82ae10180106943103ef9a Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Thu, 11 May 2023 13:22:19 -0700 Subject: [PATCH 12/16] Start refactor of #715 to specific optionals. --- app/src/processing/app/Problem.java | 74 ++++++++++++++----- .../app/syntax/PdeTextAreaPainter.java | 31 ++++---- app/src/processing/app/ui/Editor.java | 22 +++--- .../src/processing/mode/java/JavaProblem.java | 58 +++++++++++++-- .../processing/mode/java/SyntaxProblem.java | 61 ++++++++++++--- 5 files changed, 188 insertions(+), 58 deletions(-) diff --git a/app/src/processing/app/Problem.java b/app/src/processing/app/Problem.java index 2e69c8dd1a..c5f633c678 100644 --- a/app/src/processing/app/Problem.java +++ b/app/src/processing/app/Problem.java @@ -20,12 +20,29 @@ package processing.app; +import java.util.Optional; + /** * Structure describing a problem encountered in sketch compilation. */ public interface Problem { + /** + * Strategy converting line number in tab to character offset from tab start. + */ + public interface LineToTabOffsetGetter { + + /** + * Convert a line number to the number of characters past tab start. + * + * @param line The line number to convert. + * @return The number of characters past tab start where that line starts. + */ + public int get(int line); + + } + /** * Get if the problem is an error that prevented compilation. * @@ -65,32 +82,55 @@ public interface Problem { public String getMessage(); /** - * Determine against what reference point for the this Problem's specific - * location is reported. + * Get the exact character on which this problem starts in code tab relative. + * + * @return Number of characters past the start of the tab if known where the + * code associated with the Problem starts. Returns empty if not provided. + */ + public Optional getTabStartOffset(); + + /** + * Get the exact character on which this problem ends in code tab relative. + * + * @return Number of characters past the start of the tab if known where the + * code associated with the Problem ends. Returns empty if not provided. + */ + public Optional getTabStopOffset(); + + /** + * Get the exact character on which this problem starts in code line relative. + * + * @return Number of characters past the start of the line if known where the + * code associated with the Problem starts. Returns empty if not provided. + */ + public Optional getLineStartOffset(); + + /** + * Get the exact character on which this problem ends in code line relative. * - * @return True if getStartOffset and getStopOffset are number of characters - * relative to the start of the line reported by getLineNumber. False if - * getStartOffset and getStopOffset are number of characters from start of - * the tab. + * @return Number of characters past the start of the line if known where the + * code associated with the Problem ends. Returns empty if not provided. */ - public boolean usesLineOffset(); + public Optional getLineStopOffset(); /** - * Get the exact character on which this problem starts in code. + * Get the exact character on which this problem ends in code tab relative. * - * @return Number of characters past the reference point in usesLineOffset - * at which this problem starts (where the code to which the problem - * is attributed starts). + * @param strategy Strategy to convert line to tab start if needed. + * @return Number of characters past the start of the tab if known where the + * code associated with the Problem ends, using the provided conversion + * if needed. Returns line start if character position not given. */ - public int getStartOffset(); + public int computeTabStartOffset(LineToTabOffsetGetter strategy); /** - * Get the exact character on which this problem ends in code. + * Get the exact character on which this problem ends in code tab relative. * - * @return Number of characters past the reference point in usesLineOffset - * at which this problem ends (where the code to which the problem - * is attributed ends). + * @param strategy Strategy to convert line to tab start if needed. + * @return Number of characters past the start of the tab if known where the + * code associated with the Problem ends, using the provided conversion + * if needed. Returns line start if character position not given. */ - public int getStopOffset(); + public int computeTabStopOffset(LineToTabOffsetGetter strategy); } diff --git a/app/src/processing/app/syntax/PdeTextAreaPainter.java b/app/src/processing/app/syntax/PdeTextAreaPainter.java index e55fa413c2..be0d5fdc80 100644 --- a/app/src/processing/app/syntax/PdeTextAreaPainter.java +++ b/app/src/processing/app/syntax/PdeTextAreaPainter.java @@ -46,6 +46,8 @@ public class PdeTextAreaPainter extends TextAreaPainter { protected Color gutterTextInactiveColor; protected Color gutterHighlightColor; + private final Problem.LineToTabOffsetGetter lineToTabOffsetGetter; + public PdeTextAreaPainter(JEditTextArea textArea, TextAreaDefaults defaults) { super(textArea, defaults); @@ -76,6 +78,10 @@ public void mousePressed(MouseEvent event) { } } }); + + lineToTabOffsetGetter = (x) -> { + return textArea.getLineStartOffset(x); + }; } @@ -147,18 +153,14 @@ protected void paintLine(Graphics gfx, int line, int x, TokenMarkerState marker) protected void paintErrorLine(Graphics gfx, int line, int x) { List problems = getEditor().findProblems(line); for (Problem problem : problems) { - int startOffset = problem.getStartOffset(); - int stopOffset = problem.getStopOffset(); + int startOffset = problem.computeTabStartOffset(lineToTabOffsetGetter); + int stopOffset = problem.computeTabStopOffset(lineToTabOffsetGetter); - int lineOffset = textArea.getLineStartOffset(line); - - if (problem.usesLineOffset()) { - startOffset += lineOffset; - stopOffset += lineOffset; - } + int lineOffsetStart = textArea.getLineStartOffset(line); + int lineOffsetStop = textArea.getLineStopOffset(line); - int wiggleStart = Math.max(startOffset, lineOffset); - int wiggleStop = Math.min(stopOffset, textArea.getLineStopOffset(line)); + int wiggleStart = Math.max(startOffset, lineOffsetStart); + int wiggleStop = Math.min(stopOffset, lineOffsetStop); int y = textArea.lineToY(line) + getLineDisplacement(); @@ -168,7 +170,10 @@ protected void paintErrorLine(Graphics gfx, int line, int x) { try { SyntaxDocument doc = textArea.getDocument(); badCode = doc.getText(wiggleStart, wiggleStop - wiggleStart); - goodCode = doc.getText(lineOffset, wiggleStart - lineOffset); + goodCode = doc.getText( + lineOffsetStart, + wiggleStart - lineOffsetStart + ); //log("paintErrorLine() LineText GC: " + goodCode); //log("paintErrorLine() LineText BC: " + badCode); } catch (BadLocationException bl) { @@ -333,8 +338,8 @@ public String getToolTipText(MouseEvent event) { int lineStart = textArea.getLineStartOffset(line); int lineEnd = textArea.getLineStopOffset(line); - int errorStart = problem.getStartOffset(); - int errorEnd = problem.getStopOffset() + 1; + int errorStart = problem.computeTabStartOffset(lineToTabOffsetGetter); + int errorEnd = problem.computeTabStopOffset(lineToTabOffsetGetter) + 1; int startOffset = Math.max(errorStart, lineStart) - lineStart; int stopOffset = Math.min(errorEnd, lineEnd) - lineStart; diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 3cf6d7ba1d..824f8ac20a 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2556,8 +2556,15 @@ public void updateErrorTable(List problems) { public void highlight(Problem p) { + Problem.LineToTabOffsetGetter getter = (x) -> { + return textarea.getLineStartOffset(x); + }; + if (p != null) { - highlight(p.getTabIndex(), p.getStartOffset(), p.getStopOffset()); + int tabIndex = p.getTabIndex(); + int tabToStartOffset = p.computeTabStartOffset(getter); + int tabToStopOffset = p.computeTabStopOffset(getter); + highlight(tabIndex, tabToStartOffset, tabToStopOffset); } } @@ -2623,15 +2630,10 @@ public List findProblems(int line) { .filter(p -> p.getTabIndex() == currentTab) .filter(p -> { int pStartLine = p.getLineNumber(); - int pEndOffset = p.getStopOffset(); - - int pEndLine; - if (p.usesLineOffset()) { - int lineGlobalOffset = textarea.getLineStartOffset(pStartLine); - pEndLine = textarea.getLineOfOffset(pEndOffset + lineGlobalOffset); - } else { - pEndLine = textarea.getLineOfOffset(pEndOffset); - } + int pEndOffset = p.computeTabStopOffset( + (startLine) -> textarea.getLineStartOffset(pStartLine) + ); + int pEndLine = textarea.getLineOfOffset(pEndOffset); return line >= pStartLine && line <= pEndLine; }) diff --git a/java/src/processing/mode/java/JavaProblem.java b/java/src/processing/mode/java/JavaProblem.java index adf86fcab7..5233c785cb 100644 --- a/java/src/processing/mode/java/JavaProblem.java +++ b/java/src/processing/mode/java/JavaProblem.java @@ -20,6 +20,8 @@ package processing.mode.java; +import java.util.Optional; + import org.eclipse.jdt.core.compiler.IProblem; import processing.app.Problem; @@ -42,9 +44,9 @@ public class JavaProblem implements Problem { /** Line number (pde code) of the error */ private final int lineNumber; - private int startOffset; + private Optional startOffset; - private int stopOffset; + private Optional stopOffset; /** * If the error is a 'cannot find type' contains the list of suggested imports @@ -60,6 +62,8 @@ public JavaProblem(String message, int type, int tabIndex, int lineNumber) { this.type = type; this.tabIndex = tabIndex; this.lineNumber = lineNumber; + this.startOffset = Optional.empty(); + this.stopOffset = Optional.empty(); } @@ -83,22 +87,31 @@ static public JavaProblem fromIProblem(IProblem iProblem, int tabIndex, public void setPDEOffsets(int startOffset, int stopOffset){ - this.startOffset = startOffset; - this.stopOffset = stopOffset; + this.startOffset = Optional.of(startOffset); + this.stopOffset = Optional.of(stopOffset); } @Override - public int getStartOffset() { + public Optional getTabStartOffset() { return startOffset; } @Override - public int getStopOffset() { + public Optional getTabStopOffset() { return stopOffset; } + @Override + public Optional getLineStartOffset() { + return Optional.empty(); + } + + @Override + public Optional getLineStopOffset() { + return Optional.empty(); + } @Override public boolean isError() { @@ -149,4 +162,37 @@ public String toString() { + startOffset + ",LN STOP OFF: " + stopOffset + ",PROB: " + message; } + + @Override + public int computeTabStartOffset(LineToTabOffsetGetter strategy) { + Optional nativeTabStartOffset = getTabStartOffset(); + if (nativeTabStartOffset.isPresent()) { + return nativeTabStartOffset.get(); + } + + Optional lineStartOffset = getLineStartOffset(); + int lineOffset = strategy.get(getLineNumber()); + if (lineStartOffset.isPresent()) { + return lineOffset + lineStartOffset.get(); + } else { + return lineOffset; + } + } + + @Override + public int computeTabStopOffset(LineToTabOffsetGetter strategy) { + Optional nativeTabStopOffset = getTabStopOffset(); + if (nativeTabStopOffset.isPresent()) { + return nativeTabStopOffset.get(); + } + + Optional lineStopOffset = getLineStopOffset(); + int lineOffset = strategy.get(getLineNumber()); + if (lineStopOffset.isPresent()) { + return lineOffset + lineStopOffset.get(); + } else { + return lineOffset; + } + } + } diff --git a/java/src/processing/mode/java/SyntaxProblem.java b/java/src/processing/mode/java/SyntaxProblem.java index a1af0ed8b2..bf037b9717 100644 --- a/java/src/processing/mode/java/SyntaxProblem.java +++ b/java/src/processing/mode/java/SyntaxProblem.java @@ -1,5 +1,26 @@ +/* +Part of the Processing project - http://processing.org +Copyright (c) 2012-15 The Processing Foundation + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + package processing.mode.java; +import java.util.Optional; + + /** * Problem identifying a syntax error found in preprocessing. */ @@ -8,9 +29,10 @@ public class SyntaxProblem extends JavaProblem { private final int tabIndex; private final int lineNumber; private final String message; - private final int startOffset; - private final int stopOffset; - private final boolean lineFlag; + private final Optional tabStartOffset; + private final Optional tabStopOffset; + private final Optional lineStartOffset; + private final Optional lineStopOffset; /** * Create a new syntax problem. @@ -33,9 +55,18 @@ public SyntaxProblem(int newTabIndex, int newLineNumber, String newMessage, int tabIndex = newTabIndex; lineNumber = newLineNumber; message = newMessage; - startOffset = newStartOffset; - stopOffset = newStopOffset; - lineFlag = newUsesLineOffset; + + if (newUsesLineOffset) { + lineStartOffset = Optional.of(newStartOffset); + lineStopOffset = Optional.of(newStopOffset); + tabStartOffset = Optional.empty(); + tabStopOffset = Optional.empty(); + } else { + lineStartOffset = Optional.empty(); + lineStopOffset = Optional.empty(); + tabStartOffset = Optional.of(newStartOffset); + tabStopOffset = Optional.of(newStopOffset); + } } @Override @@ -64,17 +95,23 @@ public String getMessage() { } @Override - public int getStartOffset() { - return startOffset; + public Optional getTabStartOffset() { + return tabStartOffset; } @Override - public int getStopOffset() { - return stopOffset; + public Optional getTabStopOffset() { + return tabStopOffset; } - public boolean usesLineOffset() { - return lineFlag; + @Override + public Optional getLineStartOffset() { + return lineStartOffset; + } + + @Override + public Optional getLineStopOffset() { + return lineStopOffset; } } From 3ba415c7f3c08ab2cec91a7d8ed8a56d055d4407 Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Thu, 11 May 2023 13:33:45 -0700 Subject: [PATCH 13/16] Working again with optionals split. --- java/src/processing/mode/java/ErrorChecker.java | 11 +++++++++-- java/src/processing/mode/java/lsp/PdeAdapter.java | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/java/src/processing/mode/java/ErrorChecker.java b/java/src/processing/mode/java/ErrorChecker.java index 015673ed34..1302dd773a 100644 --- a/java/src/processing/mode/java/ErrorChecker.java +++ b/java/src/processing/mode/java/ErrorChecker.java @@ -277,9 +277,16 @@ static private List checkForCurlyQuotes(PreprocSketch ps) { String q = matcher.group(); int tabStart = in.startTabOffset + offset; int tabStop = tabStart + 1; + int line = ps.tabOffsetToTabLine(in.tabIndex, tabStart); + // Prevent duplicate problems - if (problems.stream().noneMatch(p -> p.getStartOffset() == tabStart)) { - int line = ps.tabOffsetToTabLine(in.tabIndex, tabStart); + boolean isDupe = problems.stream() + .filter(p -> p.getTabIndex() == in.tabIndex) + .filter(p -> p.getLineNumber() == line) + .findAny() + .isPresent(); + + if (isDupe) { String message; if (iproblem.getID() == IProblem.UnterminatedString) { message = Language.interpolate("editor.status.unterm_string_curly", q); diff --git a/java/src/processing/mode/java/lsp/PdeAdapter.java b/java/src/processing/mode/java/lsp/PdeAdapter.java index 24dc2e1d67..9e8942e272 100644 --- a/java/src/processing/mode/java/lsp/PdeAdapter.java +++ b/java/src/processing/mode/java/lsp/PdeAdapter.java @@ -233,13 +233,13 @@ void updateProblems(List problems) { new Position( prob.getLineNumber(), PdeAdapter - .toLineCol(code.getProgram(), prob.getStartOffset()) + .toLineCol(code.getProgram(), prob.getTabStartOffset().get()) .col - 1 ), new Position( prob.getLineNumber(), PdeAdapter - .toLineCol(code.getProgram(), prob.getStopOffset()) + .toLineCol(code.getProgram(), prob.getTabStopOffset().get()) .col - 1 ) ), From ecc1dc0d62368fa4fd703491268b5d3f5b178f7e Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Thu, 11 May 2023 13:38:15 -0700 Subject: [PATCH 14/16] Added asserts for PdeAdapter. --- java/src/processing/mode/java/lsp/PdeAdapter.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/java/src/processing/mode/java/lsp/PdeAdapter.java b/java/src/processing/mode/java/lsp/PdeAdapter.java index 9e8942e272..83d2b30960 100644 --- a/java/src/processing/mode/java/lsp/PdeAdapter.java +++ b/java/src/processing/mode/java/lsp/PdeAdapter.java @@ -228,18 +228,25 @@ void updateProblems(List problems) { Map> dias = problems.stream() .map(prob -> { SketchCode code = sketch.getCode(prob.getTabIndex()); + + Optional startOffset = prob.getTabStartOffset(); + Optional endOffset = prob.getTabStopOffset(); + + assert startOffset.isPresent(); + assert endOffset.isPresent(); + Diagnostic dia = new Diagnostic( new Range( new Position( prob.getLineNumber(), PdeAdapter - .toLineCol(code.getProgram(), prob.getTabStartOffset().get()) + .toLineCol(code.getProgram(), startOffset.get()) .col - 1 ), new Position( prob.getLineNumber(), PdeAdapter - .toLineCol(code.getProgram(), prob.getTabStopOffset().get()) + .toLineCol(code.getProgram(), endOffset.get()) .col - 1 ) ), From aeb72426c17467a72832919b003add2ac635b082 Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Tue, 16 May 2023 11:10:14 -0700 Subject: [PATCH 15/16] Closes #720. Fix an issue where tweaks mode wont run if there are semi-transparent colors in the tab because of a regex issue. --- .../processing/mode/java/tweak/Handle.java | 34 ++++++++++++++++--- .../mode/java/tweak/SketchParser.java | 2 +- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/java/src/processing/mode/java/tweak/Handle.java b/java/src/processing/mode/java/tweak/Handle.java index 72dfa5ed31..d1b21a74ca 100644 --- a/java/src/processing/mode/java/tweak/Handle.java +++ b/java/src/processing/mode/java/tweak/Handle.java @@ -85,12 +85,26 @@ public Handle(String t, String n, int vi, String v, int ti, int l, int sc, textFormat = "0x%x"; } else if ("webcolor".equals(type)) { - Long val = Long.parseLong(strValue.substring(1, strValue.length()), 16); + Long val; + String prefix; + if (strValue.length() == 7) { + val = Long.parseLong(strValue.substring(1, strValue.length()), 16); + prefix = ""; + } else { + String valStr = strValue.substring( + strValue.length() - 6, + strValue.length() + ); + val = Long.parseLong(valStr, 16); + prefix = strValue.substring( + 1, + strValue.length() - 6 + ); + } val = val | 0xff000000; value = newValue = val.intValue(); strNewValue = strValue; - textFormat = "#%06x"; - + textFormat = "#" + prefix + "%06x"; } else if ("float".equals(type)) { value = newValue = Float.parseFloat(strValue); strNewValue = strValue; @@ -267,7 +281,19 @@ public void sendNewValue() { } else if ("hex".equals(type)) { tweakClient.sendInt(index, newValue.intValue()); } else if ("webcolor".equals(type)) { - tweakClient.sendInt(index, newValue.intValue()); + // If full opaque color, don't spend the cycles on string processing + // which does appear to matter at high frame rates. Otherwise take the + // hit and parse back from string value with transparency. + if (strNewValue.length() == 7) { + tweakClient.sendInt(index, newValue.intValue()); + } else { + long target = Long.parseLong( + strNewValue.substring(1, strNewValue.length()), + 16 + ); + tweakClient.sendInt(index, (int) target); + } + } else if ("float".equals(type)) { tweakClient.sendFloat(index, newValue.floatValue()); } diff --git a/java/src/processing/mode/java/tweak/SketchParser.java b/java/src/processing/mode/java/tweak/SketchParser.java index 2dfedd7321..40fdffee1e 100644 --- a/java/src/processing/mode/java/tweak/SketchParser.java +++ b/java/src/processing/mode/java/tweak/SketchParser.java @@ -270,7 +270,7 @@ private void addAllHexNumbers() { * list of all hexadecimal numbers in the sketch */ private void addAllWebColorNumbers() { - Pattern p = Pattern.compile("#[A-Fa-f0-9]{6}"); + Pattern p = Pattern.compile("#([A-Fa-f0-9]{2})?[A-Fa-f0-9]{6}"); for (int i=0; i Date: Thu, 13 Jul 2023 08:36:33 -0700 Subject: [PATCH 16/16] New identifier status text. --- build/shared/lib/languages/PDE.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/shared/lib/languages/PDE.properties b/build/shared/lib/languages/PDE.properties index fb2042f225..acfead4bfb 100644 --- a/build/shared/lib/languages/PDE.properties +++ b/build/shared/lib/languages/PDE.properties @@ -420,7 +420,7 @@ editor.status.hiding_enclosing_type = The class “%s” cannot have the same na editor.status.bad.assignment = Possible error on variable assignment near ‘%s’? editor.status.bad.generic = Possibly missing type in generic near ‘%s’? -editor.status.bad.identifier = Bad identifier? Did you forget a variable or start an identifier with digits near ‘%s’? +editor.status.bad.identifier = There's an issue with a "bad identifier" in your code near '%s'. editor.status.bad.parameter = Error on parameter or method declaration near ‘%s’? editor.status.bad.import = Import not allowed here. editor.status.bad.mixed_mode = You may be mixing active and static modes.