SwitchOnStringCandidate (@NotNull SwitchStatement firstSwitch, @NotNull InvocationExprent switchSelector) { if (switchSelector.getInstance().type != Exprent.EXPRENT_VAR) return null; if (!switchSelector.isInstanceCall(ClassNameConstants.JAVA_LANG_STRING, "hashCode", 0)) return null; Set<Object> realCaseValueHashCodes = findRealCaseValuesHashCodes(firstSwitch); VarExprent firstSwitchSelectorQualifier = (VarExprent)switchSelector.getInstance(); VarExprent tmpVarAssignTo = null; SwitchStatement secondSwitch = null; Map<Integer, String> mappedCaseLabelValues = new HashMap<>(); for (Statement statement : firstSwitch.getCaseStatements()) { if (statement.type != StatementType.IF) { Statement defaultStatement = firstSwitch.getDefaultEdge().getDestination(); if (defaultStatement != statement) return null; continue; } IfStatement ifStatement = (IfStatement)statement; String caseLabelValue = findRealCaseValue(ifStatement, firstSwitchSelectorQualifier); if (caseLabelValue == null) return null; if (!realCaseValueHashCodes.remove(caseLabelValue.hashCode())) return null; if (ifStatement.getIfstat() == null) return null; List<Exprent> ifStatementExprents = ifStatement.getIfstat().getExprents(); if (ifStatementExprents == null || ifStatementExprents.size() != 1) return null; if (ifStatementExprents.get(0).type != Exprent.EXPRENT_ASSIGNMENT) return null; AssignmentExprent assignment = (AssignmentExprent)ifStatementExprents.get(0); if (assignment.getLeft().type != Exprent.EXPRENT_VAR || assignment.getRight().type != Exprent.EXPRENT_CONST) return null; // tmp variable should be the same for all assignments if (tmpVarAssignTo != null && !tmpVarAssignTo.equals(assignment.getLeft())) return null; tmpVarAssignTo = (VarExprent)assignment.getLeft(); Object valueAssignedToTmpVar = ((ConstExprent)assignment.getRight()).getValue(); if (!(valueAssignedToTmpVar instanceof Integer)) return null; mappedCaseLabelValues.put((Integer)valueAssignedToTmpVar, caseLabelValue); if (ifStatement.getLabelEdges().size() != 1) return null; Statement edgeDestination = ifStatement.getLabelEdges().iterator().next().getDestination(); if (edgeDestination.type == StatementType.SEQUENCE) { edgeDestination = edgeDestination.getFirst(); } if (edgeDestination.type != StatementType.SWITCH) return null; // the switch should be the same for all case labels if (secondSwitch != null && secondSwitch != edgeDestination) return null; secondSwitch = (SwitchStatement)edgeDestination; } if (secondSwitch == null || !realCaseValueHashCodes.isEmpty()) return null; Exprent siblingSwitchExprent = secondSwitch.getHeadExprent(); if (siblingSwitchExprent == null) return null; if (siblingSwitchExprent.type != Exprent.EXPRENT_SWITCH) return null; if (!tmpVarAssignTo.equals(((SwitchExprent)siblingSwitchExprent).getValue())) return null; Exprent secondSwitchSelector = secondSwitch.getHeadExprent(); if (secondSwitchSelector == null || secondSwitchSelector.type != Exprent.EXPRENT_SWITCH) return null; Statement firstStatementInFirstSwitch = firstSwitch.getFirst(); if (firstStatementInFirstSwitch.type != StatementType.BASIC_BLOCK) return null; Statement firstStatementInSecondSwitch = secondSwitch.getFirst(); if (firstStatementInSecondSwitch.type != StatementType.BASIC_BLOCK) return null; List<Exprent> firstSwitchExprents = firstStatementInFirstSwitch.getExprents(); if (firstSwitchExprents == null || firstStatementInSecondSwitch.getExprents() == null) return null; return new SwitchOnStringCandidate.JavacSwitchCandidate(firstSwitch, firstSwitchSelectorQualifier, tmpVarAssignTo, secondSwitch, mappedCaseLabelValues, firstSwitchExprents, secondSwitchSelector, firstStatementInSecondSwitch); }