This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 3cf0433370 Minor tweak: use bitset instead
3cf0433370 is described below

commit 3cf0433370ef992c30cb42c64e84eb87799cdf03
Author: Daniel Sun <[email protected]>
AuthorDate: Sat Jul 18 16:49:47 2026 +0900

    Minor tweak: use bitset instead
---
 src/antlr/GroovyLexer.g4                           | 42 +++++++++++++---------
 .../groovy/parser/antlr4/SemanticPredicates.java   | 26 ++++++++++----
 2 files changed, 45 insertions(+), 23 deletions(-)

diff --git a/src/antlr/GroovyLexer.g4 b/src/antlr/GroovyLexer.g4
index c5215b4c1c..dabef396b9 100644
--- a/src/antlr/GroovyLexer.g4
+++ b/src/antlr/GroovyLexer.g4
@@ -79,27 +79,35 @@ options {
         super.emit(token);
     }
 
-    private static final int[] REGEX_CHECK_ARRAY = {
-        DEC,
-        INC,
-        THIS,
-        RBRACE,
-        RBRACK,
-        RPAREN,
-        GStringEnd,
-        NullLiteral,
-        StringLiteral,
-        BooleanLiteral,
-        IntegerLiteral,
-        FloatingPointLiteral,
-        Identifier, CapitalizedIdentifier
-    };
+    /**
+     * Token types after which {@code /.../} must not be treated as a slashy 
string
+     * (e.g. {@code a++ / b}, {@code list[i] / n}). {@link java.util.BitSet} 
gives
+     * O(1) membership tests on this hot decision.
+     */
+    private static final BitSet REGEX_CHECK_SET = new BitSet();
     static {
-        Arrays.sort(REGEX_CHECK_ARRAY);
+        int[] regexCheckTypes = {
+            DEC,
+            INC,
+            THIS,
+            RBRACE,
+            RBRACK,
+            RPAREN,
+            GStringEnd,
+            NullLiteral,
+            StringLiteral,
+            BooleanLiteral,
+            IntegerLiteral,
+            FloatingPointLiteral,
+            Identifier, CapitalizedIdentifier
+        };
+        for (int t : regexCheckTypes) {
+            REGEX_CHECK_SET.set(t);
+        }
     }
 
     private boolean isRegexAllowed() {
-        return (Arrays.binarySearch(REGEX_CHECK_ARRAY, this.lastTokenType) < 
0);
+        return !REGEX_CHECK_SET.get(this.lastTokenType);
     }
 
     /**
diff --git 
a/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java 
b/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
index b9fd07fc91..ecab4f2c0e 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
@@ -24,7 +24,7 @@ import org.antlr.v4.runtime.TokenStream;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ModifierNode;
 
-import java.util.Arrays;
+import java.util.BitSet;
 import java.util.regex.Pattern;
 
 import static org.apache.groovy.parser.antlr4.GroovyParser.ASSIGN;
@@ -147,9 +147,23 @@ public class SemanticPredicates {
                 && LPAREN == (ts.LT(2).getType());
     }
 
-    private static final int[] MODIFIER_ARRAY =
-            ModifierNode.MODIFIER_OPCODE_MAP.keySet().stream()
-                    .mapToInt(Integer::intValue).sorted().toArray();
+    private static final BitSet MODIFIER_TYPES = new BitSet();
+    static {
+        for (Integer tokenType : ModifierNode.MODIFIER_OPCODE_MAP.keySet()) {
+            if (tokenType != null && tokenType >= 0) {
+                MODIFIER_TYPES.set(tokenType);
+            }
+        }
+    }
+
+    /**
+     * O(1) modifier-token membership. Negative types (e.g. {@link Token#EOF}) 
are never
+     * modifiers
+     */
+    private static boolean isModifierType(final int tokenType) {
+        return tokenType >= 0 && MODIFIER_TYPES.get(tokenType);
+    }
+
     /**
      * Distinguish between local variable declaration and method call, e.g. `a 
b`
      */
@@ -184,7 +198,7 @@ public class SemanticPredicates {
         int nextCodePoint = token.getText().codePointAt(0);
 
         return // VOID == tokenType ||
-                !(BuiltInPrimitiveType == tokenType || 
Arrays.binarySearch(MODIFIER_ARRAY, tokenType) >= 0)
+                !(BuiltInPrimitiveType == tokenType || 
isModifierType(tokenType))
                         && !Character.isUpperCase(nextCodePoint)
                         && nextCodePoint != '@'
                         && !(ASSIGN == tokenType3 || (LT == tokenType2 || 
LBRACK == tokenType2))
@@ -212,7 +226,7 @@ public class SemanticPredicates {
             if (ts.LT(idx).getType() == LPAREN) {
                 idx++;
                 int depth = 1;
-                while (depth > 0 && ts.LT(idx).getType() != 
org.antlr.v4.runtime.Token.EOF) {
+                while (depth > 0 && ts.LT(idx).getType() != Token.EOF) {
                     int t = ts.LT(idx++).getType();
                     if (t == LPAREN) depth++;
                     else if (t == RPAREN) depth--;

Reply via email to