From 0ded19858192058b1fa5be56632d614086bdef28 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Fri, 24 Apr 2026 19:26:35 +0000 Subject: [PATCH] perf(detector): hoist inline Pattern.compile to static finals (RAN-32) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes regex recompilation from hot paths in three Java detectors. Each inline Pattern.compile() call inside detect() now references a private static final Pattern compiled once at class load. - ConfigDefDetector: VALUE_KEY_RE, QUOTED_STRING_RE - KafkaDetector: QUOTED_TOPIC_RE - SpringRestDetector: BARE_QUOTED_RE Pure refactor — same regex source, same flags. All 344 affected detector tests pass. Co-Authored-By: Paperclip --- .../iq/detector/jvm/java/ConfigDefDetector.java | 6 ++++-- .../randomcodespace/iq/detector/jvm/java/KafkaDetector.java | 3 ++- .../iq/detector/jvm/java/SpringRestDetector.java | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ConfigDefDetector.java b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ConfigDefDetector.java index e39fd26d..bf19a48c 100644 --- a/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ConfigDefDetector.java +++ b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ConfigDefDetector.java @@ -44,6 +44,8 @@ public class ConfigDefDetector extends AbstractJavaParserDetector { private static final Pattern DEFINE_RE = Pattern.compile("\\.define\\s*\\(\\s*\"([^\"]+)\""); private static final Pattern VALUE_RE = Pattern.compile("@Value\\s*\\(\\s*\"\\$\\{([^}]+)\\}\""); private static final Pattern CONFIG_PROPS_RE = Pattern.compile("@ConfigurationProperties\\s*\\(\\s*(?:prefix\\s*=\\s*)?\"([^\"]+)\""); + private static final Pattern VALUE_KEY_RE = Pattern.compile("\"\\$\\{([^}]+)\\}\""); + private static final Pattern QUOTED_STRING_RE = Pattern.compile("\"([^\"]+)\""); private static final String VALUE_ANNOTATION = "Value"; private static final String CONFIG_PROPS_ANNOTATION = "ConfigurationProperties"; @@ -157,7 +159,7 @@ private DetectorResult detectWithAst(CompilationUnit cu, DetectorContext ctx) { private Optional extractValueKey(AnnotationExpr ann) { // @Value("${some.key}") or @Value(value = "${some.key}") String raw = ann.toString(); - Matcher m = Pattern.compile("\"\\$\\{([^}]+)\\}\"").matcher(raw); + Matcher m = VALUE_KEY_RE.matcher(raw); if (m.find()) return Optional.of(m.group(1)); return Optional.empty(); } @@ -165,7 +167,7 @@ private Optional extractValueKey(AnnotationExpr ann) { private Optional extractAnnotationStringValue(AnnotationExpr ann) { // @ConfigurationProperties("prefix") or @ConfigurationProperties(prefix = "prefix") String raw = ann.toString(); - Matcher m = Pattern.compile("\"([^\"]+)\"").matcher(raw); + Matcher m = QUOTED_STRING_RE.matcher(raw); if (m.find()) return Optional.of(m.group(1)); return Optional.empty(); } diff --git a/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/KafkaDetector.java b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/KafkaDetector.java index 90bcb818..721f3a72 100644 --- a/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/KafkaDetector.java +++ b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/KafkaDetector.java @@ -39,6 +39,7 @@ public class KafkaDetector extends AbstractRegexDetector { private static final Pattern KAFKA_SEND_RE = Pattern.compile( "(?:kafkaTemplate|KafkaTemplate)\\s*\\.send\\s*\\(\\s*\"([^\"]+)\""); private static final Pattern GROUP_ID_RE = Pattern.compile("groupId\\s*=\\s*\"([^\"]+)\""); + private static final Pattern QUOTED_TOPIC_RE = Pattern.compile("\"([^\"]+)\""); @Override public String getName() { @@ -84,7 +85,7 @@ public DetectorResult detect(DetectorContext ctx) { Matcher m = KAFKA_LISTENER_RE.matcher(lines[i]); if (!m.find()) { if (i > 0 && lines[i - 1].contains("@KafkaListener")) { - Matcher fallback = Pattern.compile("\"([^\"]+)\"").matcher(lines[i]); + Matcher fallback = QUOTED_TOPIC_RE.matcher(lines[i]); if (fallback.find()) { String topic = fallback.group(1); String topicId = ensureTopicNode(topic, seenTopics, nodes, registry); diff --git a/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/SpringRestDetector.java b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/SpringRestDetector.java index c96a2f5a..104b62ce 100644 --- a/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/SpringRestDetector.java +++ b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/SpringRestDetector.java @@ -74,6 +74,7 @@ public class SpringRestDetector extends AbstractJavaParserDetector { // ---- HTTP client patterns (for CALLS edge emission) ---- private static final Pattern REST_TEMPLATE_RE = Pattern.compile("RestTemplate"); private static final Pattern WEB_CLIENT_RE = Pattern.compile("WebClient"); + private static final Pattern BARE_QUOTED_RE = Pattern.compile("\"([^\"]*)\""); private static final Pattern FEIGN_CLIENT_RE = Pattern.compile( "@FeignClient\\s*\\(\\s*(?:name\\s*=\\s*)?[\"']([^\"']+)[\"']"); @@ -342,7 +343,7 @@ private DetectorResult detectWithRegex(DetectorContext ctx) { String path = extractAttr(attrStr, VALUE_RE); if (path == null && attrStr != null) { - Matcher bare = Pattern.compile("\"([^\"]*)\"").matcher(attrStr); + Matcher bare = BARE_QUOTED_RE.matcher(attrStr); if (bare.find()) path = bare.group(1); } if (path == null) path = "";