List<PatternVariableCandidate> (@NotNull PatternVariableCandidate previousCandidate, @NotNull Statement caseStatement, @NotNull Set<AssignmentExprent> usedAssignmentExprents, @NotNull VarTracker varTracker) { Set<AssignmentExprent> toAddAssignmentExprent = new HashSet<>(); List<PatternVariableCandidate> defaultValue = new ArrayList<>(); defaultValue.add(previousCandidate); Statement currentStatement = previousCandidate.getNextStatement(); VBStyleCollection<Statement, Integer> currentStats = currentStatement.getStats(); if (currentStats.isEmpty()) { return defaultValue; } SwitchStatement nestedSwitchStatement = null; if (!caseStatement.getLabelEdges().isEmpty()) { //example: //Sequence // Switch // case default // case pattern // initializers // DoStatement // DoStatement // nested Switch Statement nextStatement = previousCandidate.getNextStatement(); if (!(nextStatement instanceof SequenceStatement sequenceStatement && sequenceStatement.getStats().size() == 1 && sequenceStatement.getStats().get(0) instanceof BasicBlockStatement && caseStatement.getLabelEdges().size() == 1)) { return defaultValue; } StatEdge edge = caseStatement.getLabelEdges().iterator().next(); if (!(edge.getType() == EdgeType.BREAK && edge.getDestination() instanceof DoStatement upperDoStatement && upperDoStatement.getConditionExprent() == null && upperDoStatement.getStats().size() == 1 && upperDoStatement.getStats().get(0) instanceof DoStatement nestedDoStatement && nestedDoStatement.getConditionExprent() == null && nestedDoStatement.getStats().size() == 1 && nestedDoStatement.getStats().get(0) instanceof SwitchStatement switchStatement)) { return defaultValue; } if (!(caseStatement.getParent() instanceof SwitchStatement upperSwitchStatement && upperSwitchStatement.getCaseStatements().size() == 2)) { return defaultValue; } int indexCurrentStat = upperSwitchStatement.getCaseStatements().indexOf(caseStatement); if (indexCurrentStat == -1) { return defaultValue; } int indexDefaultStatement = indexCurrentStat == 0 ? 1 : 0; if (!upperSwitchStatement.getCaseEdges() .get(indexDefaultStatement) .contains(upperSwitchStatement.getDefaultEdge())) { return defaultValue; } Statement defaultStatement = upperSwitchStatement.getCaseStatements().get(indexDefaultStatement); if (defaultStatement.getExprents() == null) { return defaultValue; } for (Exprent defaultExprent : defaultStatement.getExprents()) { if (defaultExprent instanceof AssignmentExprent assignmentExprent) { toAddAssignmentExprent.add(assignmentExprent); } } nestedSwitchStatement = switchStatement; } //current is switch else if (currentStats.get(0) instanceof SwitchStatement switchStatement) { nestedSwitchStatement = switchStatement; } else { if (currentStats.size() < 2) { return defaultValue; } if (!(currentStats.get(0) instanceof BasicBlockStatement)) { return defaultValue; } //Example: //Sequence // BasicBlock // Switch if (currentStats.get(1) instanceof SwitchStatement switchStatement) { nestedSwitchStatement = switchStatement; } //Example: //Sequence // BasicBlock // Do // Switch if (currentStats.get(1) instanceof DoStatement doStatement && !doStatement.getStats().isEmpty() && doStatement.getStats().get(0) instanceof SwitchStatement switchStatement) { nestedSwitchStatement = switchStatement; } //Example: //Sequence // BasicBlock // Do // Sequence // Switch if (currentStats.get(1) instanceof DoStatement doStatement && doStatement.getStats().size() == 1 && doStatement.getStats().get(0) instanceof SequenceStatement sequenceStatement && sequenceStatement.getStats().size() == 2 && sequenceStatement.getStats().get(0) instanceof SwitchStatement newSwitchStatement) { nestedSwitchStatement = newSwitchStatement; } if (currentStats.get(1) instanceof DoStatement doStatement && doStatement.getStats().size() == 1 && doStatement.getStats().get(0) instanceof DoStatement nestedDoStatement && nestedDoStatement.getStats().size() == 1 && nestedDoStatement.getStats().get(0) instanceof SwitchStatement newSwitchStatement) { nestedSwitchStatement = newSwitchStatement; } } if (nestedSwitchStatement == null) { return defaultValue; } if (!(nestedSwitchStatement.getHeadExprent() instanceof SwitchExprent switchExprent && switchExprent.getValue() instanceof InvocationExprent invocationExprent)) { return defaultValue; } SwitchOnReferenceCandidate recognized = new JavacReferenceFinder(varTracker, myTypeVars, nestedSwitchStatement, invocationExprent).findCandidate(); if (recognized == null) { return defaultValue; } VarExprent exprent = previousCandidate.getVarExprent(); if (!(exprent instanceof RecordVarExprent currentRecordDeconstruction)) { return defaultValue; } RecordVarExprent component = currentRecordDeconstruction.getDirectComponent(recognized.myPreviousSelector.getInstance()); if (component == null) { return defaultValue; } ArrayList<PatternVariableCandidate> candidates = new ArrayList<>(); Map<Integer, String> classes = getMapCaseClasses(recognized.myPreviousSelector.getBootstrapArguments()); for (FullCase fullCase : recognized.mySortedCasesFromRoot) { List<Exprent> fullCaseExprents = fullCase.exprents; Statement nestedStatement = fullCase.statement; List<StatEdge> edges = nestedStatement.getSuccessorEdges(EdgeType.DIRECT_ALL); if (edges.size() == 1) { StatEdge edge = edges.get(0); //not accurate, but it is hard to track all labels here if ((edge.getType() == EdgeType.CONTINUE || edge.getType() == EdgeType.BREAK) && nestedStatement.getExprents() != null) { for (Exprent nestedExprent : nestedStatement.getExprents()) { if (nestedExprent instanceof AssignmentExprent assignmentExprent && assignmentExprent.getLeft() instanceof VarExprent left && myTypeVars.contains(left)) { toAddAssignmentExprent.add(assignmentExprent); } } } } List<PatternContainer.PatternStatement> nestedPatterns = recognized.myPatternContainer.getPatterns(nestedStatement); //process literals if (nestedPatterns == null || nestedPatterns.isEmpty()) { if (fullCaseExprents.size() == 2) { //delete null if (fullCaseExprents.get(0) instanceof ConstExprent constExprent && constExprent.getIntValue() == -1) { fullCaseExprents.remove(fullCaseExprents.get(0)); } } if (fullCaseExprents.size() != 1) { return null; } if (fullCaseExprents.get(0) == null) { continue; } if (!(fullCaseExprents.get(0) instanceof ConstExprent constExprent)) { return null; } String newClassName = classes.get(constExprent.getIntValue()); if (newClassName == null) { return null; } RecordVarExprent copy = currentRecordDeconstruction.copy(); RecordVarExprent toReplace = copy.getDirectComponent(recognized.myPreviousSelector.getInstance()); if (toReplace == null) { return null; } toReplace.setVarType(new VarType(newClassName)); PatternVariableCandidate nestedPatternVariableCandidate = new PatternVariableCandidate(copy, fullCase.statement(), previousCandidate.getUsedIfStatement(), previousCandidate.getTempVarAssignments(), previousCandidate.getCleaner()); candidates.add(nestedPatternVariableCandidate); } else { //process patterns for (PatternContainer.PatternStatement nestedPattern : nestedPatterns) { RecordVarExprent copy; if (nestedPattern.variable instanceof RecordVarExprent recordVarExprent) { copy = recordVarExprent; } else { if (nestedPattern.variable == null) { return null; } copy = currentRecordDeconstruction.copy(); RecordVarExprent toReplace = copy.getDirectComponent(recognized.myPreviousSelector.getInstance()); if (toReplace == null) { return null; } if (!toReplace.copyFrom(nestedPattern.variable)) { return null; } } PatternVariableCandidate nestedPatternVariableCandidate = new PatternVariableCandidate(copy, nestedPattern.caseStatement, previousCandidate.getUsedIfStatement(), previousCandidate.getTempVarAssignments(), previousCandidate.getCleaner()); nestedPatternVariableCandidate.setGuards(nestedPattern.guard); candidates.add(nestedPatternVariableCandidate); } } } if (!candidates.isEmpty()) { candidates.get(0).getTempAssignments().addAll(recognized.myTempVarAssignments); } usedAssignmentExprents.addAll(recognized.myUsedTypeVarAssignments); usedAssignmentExprents.addAll(toAddAssignmentExprent); myUsedSwitch.add(nestedSwitchStatement); return candidates; }