Skip to content

Commit 8f1ce18

Browse files
aksOpsPaperclip-Paperclipclaude
authored
fix(spotbugs): eliminate 12 SpotBugs findings (RAN-23) (#71)
Resolves RAN-23. | File | Finding | Fix | |---|---|---| | CodeIqApplication.java:57-58 | DLS_DEAD_LOCAL_STORE (isIndex, isEnrich) | Remove unused locals; only isServe drives profile selection. | | analyzer/Analyzer.java:279 | DLS_DEAD_LOCAL_STORE (fileInventory) | Drop the never-read buildFileInventory call and its now-orphan helper + unused imports. | | analyzer/Analyzer.java:388-389 | DLS_DEAD_LOCAL_STORE (flushed, recoveredEdges) | Drop the locals but keep flush()/flushDeferred() calls for their side effects (provenance stamping, dropped-edge counter). | | cache/AnalysisCache.java:114,151 | CT_CONSTRUCTOR_THROW x2 | Mark class final to neutralize finalizer-subclass attack on partially constructed instance. | | cli/EnrichCommand.java:153-154 | DLS_DEAD_LOCAL_STORE (flushed, recoveredEdges) | Same as Analyzer -- drop locals, keep calls. | | cli/EnrichCommand.java:425 | REC_CATCH_EXCEPTION | Narrow catch(Exception) to catch(IOException \| RuntimeException). | | detector/frontend/ReactComponentDetector.java:113 | UC_USELESS_OBJECT (allDetected) | Delete -- never queried. | | detector/go/GoStructuresDetector.java:142 | UC_USELESS_OBJECT (methodPositions) | Delete -- never read; methodStarts is built from scratch lower down. | | query/TopologyService.java:198 | UC_USELESS_OBJECT (edgeKinds) | Delete the map and its put -- blast-radius never uses it. | Also fixes a pre-existing DE_MIGHT_IGNORE at FileDiscovery.java:167 that SpotBugs only surfaced once the original 12 cleared (empty catch on Files.size() IOException). No changes to spotbugs-exclude.xml. Verification: - mvn spotbugs:check -- BugInstance size is 0 (BUILD SUCCESS). - Unblocks RAN-24 (binding spotbugs:check to mvn verify). Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0b47514 commit 8f1ce18

8 files changed

Lines changed: 17 additions & 38 deletions

File tree

src/main/java/io/github/randomcodespace/iq/CodeIqApplication.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ public static void main(String[] args) {
5454
.findFirst()
5555
.orElse("");
5656
boolean isServe = "serve".equalsIgnoreCase(command);
57-
boolean isIndex = "index".equalsIgnoreCase(command);
58-
boolean isEnrich = "enrich".equalsIgnoreCase(command);
5957

6058
if (isServe) {
6159
app.setAdditionalProfiles("serving");

src/main/java/io/github/randomcodespace/iq/analyzer/Analyzer.java

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
import io.github.randomcodespace.iq.detector.DetectorResult;
1616
import io.github.randomcodespace.iq.detector.DetectorUtils;
1717
import io.github.randomcodespace.iq.grammar.AntlrParserFactory;
18-
import io.github.randomcodespace.iq.intelligence.FileClassification;
19-
import io.github.randomcodespace.iq.intelligence.FileEntry;
20-
import io.github.randomcodespace.iq.intelligence.FileInventory;
2118
import io.github.randomcodespace.iq.intelligence.RepositoryIdentity;
2219
import io.github.randomcodespace.iq.model.CodeEdge;
2320
import io.github.randomcodespace.iq.model.CodeNode;
@@ -274,9 +271,8 @@ private AnalysisResult runWithCache(Path root, Integer parallelism, AnalysisCach
274271
int totalFiles = files.size();
275272
report.accept("Found " + totalFiles + " files");
276273

277-
// 1b. Resolve repository identity and build file inventory
274+
// 1b. Resolve repository identity
278275
RepositoryIdentity repoIdentity = RepositoryIdentity.resolve(root);
279-
FileInventory fileInventory = buildFileInventory(files, cache);
280276

281277
// Compute language breakdown
282278
Map<String, Integer> languageBreakdown = new HashMap<>();
@@ -384,9 +380,12 @@ private AnalysisResult runWithCache(Path root, Integer parallelism, AnalysisCach
384380
report.accept("Linking cross-file relationships...");
385381
builder.runLinkers(linkers);
386382

387-
// Flush and collect deferred edges
388-
GraphBuilder.FlushResult flushed = builder.flush();
389-
List<io.github.randomcodespace.iq.model.CodeEdge> recoveredEdges = builder.flushDeferred();
383+
// Flush buffered graph state and retry any deferred edges so the
384+
// side effects (provenance stamping, edge validation, dropped-edge
385+
// counters) still run even though we read the results straight off
386+
// the builder below.
387+
builder.flush();
388+
builder.flushDeferred();
390389

391390
// 5. Classify layers
392391
report.accept("Classifying layers...");
@@ -1619,22 +1618,6 @@ private DetectorResult analyzeFileRegexOnly(DiscoveredFile file, Path repoPath,
16191618
return DetectorResult.of(allNodes, allEdges);
16201619
}
16211620

1622-
/**
1623-
* Build a deterministic FileInventory from the list of discovered files.
1624-
* Content hashes are reused from {@code cache} when available (no re-read of files).
1625-
* Hashes remain null for files not yet present in the cache.
1626-
*/
1627-
private static FileInventory buildFileInventory(List<DiscoveredFile> files, AnalysisCache cache) {
1628-
List<FileEntry> entries = new ArrayList<>(files.size());
1629-
for (DiscoveredFile f : files) {
1630-
String relPath = f.path().toString().replace('\\', '/');
1631-
FileClassification cls = FileEntry.classify(relPath, f.language());
1632-
String contentHash = cache != null ? cache.getHashForPath(relPath) : null;
1633-
entries.add(new FileEntry(relPath, f.language(), f.sizeBytes(), contentHash, cls));
1634-
}
1635-
return new FileInventory(entries);
1636-
}
1637-
16381621
/**
16391622
* Get the current git HEAD commit SHA, or null if not a git repo.
16401623
*/

src/main/java/io/github/randomcodespace/iq/analyzer/FileDiscovery.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ private void addGitDiscoveredFile(Path root, List<DiscoveredFile> result, String
165165
try {
166166
size = Files.size(absPath);
167167
} catch (IOException e) {
168+
log.debug("Skipping {} -- could not read size", absPath, e);
168169
return;
169170
}
170171
long maxSize = CONFIG_LANGUAGES.contains(language)

src/main/java/io/github/randomcodespace/iq/cache/AnalysisCache.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* Uses H2 in embedded mode — pure Java, no JNI, MVCC concurrency,
3636
* fully compatible with virtual threads.
3737
*/
38-
public class AnalysisCache implements Closeable {
38+
public final class AnalysisCache implements Closeable {
3939

4040
private static final Logger log = LoggerFactory.getLogger(AnalysisCache.class);
4141

src/main/java/io/github/randomcodespace/iq/cli/EnrichCommand.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import picocli.CommandLine.Command;
2323
import picocli.CommandLine.Parameters;
2424

25+
import java.io.IOException;
2526
import java.nio.file.Files;
2627
import java.nio.file.Path;
2728
import java.text.NumberFormat;
@@ -149,9 +150,12 @@ private int enrichFromCache(AnalysisCache cache, Path root, NumberFormat nf, Ins
149150
builder.addEdges(allEdges);
150151
builder.runLinkers(linkers);
151152

152-
// Flush and collect valid edges
153-
GraphBuilder.FlushResult flushed = builder.flush();
154-
List<CodeEdge> recoveredEdges = builder.flushDeferred();
153+
// Flush buffered graph state and retry any deferred edges so the
154+
// side effects (provenance stamping, edge validation, dropped-edge
155+
// counters) still run even though we read enriched nodes/edges
156+
// straight off the builder below.
157+
builder.flush();
158+
builder.flushDeferred();
155159

156160
List<CodeNode> enrichedNodes = new ArrayList<>(builder.getNodes());
157161
List<CodeEdge> enrichedEdges = new ArrayList<>(builder.getEdges());
@@ -422,7 +426,7 @@ private int enrichFromCache(AnalysisCache cache, Path root, NumberFormat nf, Ins
422426

423427
return 0;
424428

425-
} catch (Exception e) {
429+
} catch (IOException | RuntimeException e) {
426430
log.error("Enrichment failed", e);
427431
CliOutput.error("Enrichment failed: " + e.getMessage());
428432
return 1;

src/main/java/io/github/randomcodespace/iq/detector/frontend/ReactComponentDetector.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,6 @@ record ComponentEntry(String name, String sourceId, int matchStart) {}
110110

111111
// RENDERS edges: scope JSX tag search to each component's body section.
112112
// A component's body is from its match position to the next component's position.
113-
Set<String> allDetected = new HashSet<>(componentNames);
114-
allDetected.addAll(hookNames);
115-
116113
componentEntries.sort(Comparator.comparingInt(ComponentEntry::matchStart));
117114

118115
for (int i = 0; i < componentEntries.size(); i++) {

src/main/java/io/github/randomcodespace/iq/detector/go/GoStructuresDetector.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,7 @@ protected DetectorResult detectWithRegex(DetectorContext ctx) {
139139

140140
// Methods
141141
Matcher mm = METHOD_RE.matcher(text);
142-
Set<Integer> methodPositions = new HashSet<>();
143142
while (mm.find()) {
144-
methodPositions.add(mm.start());
145143
String receiver = mm.group(1);
146144
String methodName = mm.group(2);
147145
boolean exported = Character.isUpperCase(methodName.charAt(0));

src/main/java/io/github/randomcodespace/iq/query/TopologyService.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,12 @@ public Map<String, Object> serviceDependents(String serviceName, List<CodeNode>
195195
public Map<String, Object> blastRadius(String nodeId, List<CodeNode> nodes, List<CodeEdge> edges) {
196196
// Build adjacency for BFS
197197
Map<String, List<String>> adjacency = new HashMap<>();
198-
Map<String, EdgeKind> edgeKinds = new HashMap<>();
199198
for (CodeEdge edge : edges) {
200199
if (!RUNTIME_EDGES.contains(edge.getKind())) continue;
201200
String src = edge.getSourceId();
202201
String tgt = edge.getTarget() != null ? edge.getTarget().getId() : null;
203202
if (src == null || tgt == null) continue;
204203
adjacency.computeIfAbsent(src, k -> new ArrayList<>()).add(tgt);
205-
edgeKinds.put(src + "->" + tgt, edge.getKind());
206204
}
207205

208206
// BFS from nodeId, max depth 5

0 commit comments

Comments
 (0)