PatternVariableCandidate (@NotNull Statement parent, @NotNull VarTracker varTracker) { if (!(parent instanceof SequenceStatement)) { return null; } if (checkRegularEdgesForRecordPattern(parent)) return null; Set<IfStatement> ifStatements = new HashSet<>(); VBStyleCollection<Statement, Integer> stats = parent.getStats(); if (stats.size() < 3) { return null; } int i = 0; //It is possible to have false positive or false negative results here, and it is hard to exclude that. //Let's keep it simple at least while (true) { if (!(stats.size() > i + 1 && stats.get(i) instanceof BasicBlockStatement basicBlockStatement && stats.get(i + 1) instanceof CatchStatement catchStatement)) { if (i != 0) { break; } return null; } //the first block must contain only assignments which can be gathered if (!processFullBlock(varTracker, basicBlockStatement)) { return null; } //a catch section with call for a record component if (!processCatchStatement(varTracker, catchStatement)) { return null; } i += 2; } int nextIndex = i; List<TempVarAssignmentItem> tempVarAssignmentItems = new ArrayList<>(); if (!processAtLeastOneBlock(varTracker, stats.get(nextIndex))) { tempVarAssignmentItems.addAll(varTracker.getTempItems()); //without reassigning Object SequenceStatement sequenceStatement = new SequenceStatement((parent.getStats().subList(nextIndex, parent.getStats().size()))); return new PatternVariableCandidate(varTracker.root, sequenceStatement, new HashSet<>(), tempVarAssignmentItems, () -> { sequenceStatement.getStats().forEach(stat->stat.setParent(sequenceStatement)); parent.getParent().replaceStatement(parent, sequenceStatement); }); } //R(String s), there is the next if-statement, which defines the next class if (stats.get(nextIndex) instanceof IfStatement ifStatement && stats.size() - 1 == nextIndex) { PatternVariableCandidate nestedCandidate = findRecursivelyInstanceOfIfStatement(stats.get(nextIndex), varTracker, tempVarAssignmentItems); if (nestedCandidate != null) { ifStatements.add(ifStatement); ifStatements.addAll(nestedCandidate.getUsedIfStatement()); tempVarAssignmentItems.addAll(varTracker.getTempItems()); tempVarAssignmentItems.addAll(nestedCandidate.getTempVarAssignments()); return new PatternVariableCandidate(varTracker.root, nestedCandidate.getNextStatement(), ifStatements, tempVarAssignmentItems, () -> { nestedCandidate.getCleaner().run(); parent.getParent().replaceStatement(parent, ifStatement.getIfstat()); }); } } //R(Object o), without defining the next class. tempVarAssignmentItems.addAll(varTracker.getTempItems()); SequenceStatement sequenceStatement = new SequenceStatement((parent.getStats().subList(nextIndex, parent.getStats().size()))); return new PatternVariableCandidate(varTracker.root, sequenceStatement, new HashSet<>(), tempVarAssignmentItems, () -> { sequenceStatement.getStats().forEach(stat->stat.setParent(sequenceStatement)); parent.getParent().replaceStatement(parent, sequenceStatement); }); }