@Override public void visitCaseSection(GrCaseSection caseSection) { for (GrCaseLabel label : caseSection.getCaseLabels()) { GrExpression value = label.getValue(); if (value != null) { value.accept(this); } } final GrStatement[] statements = caseSection.getStatements(); // infer 'may be return' position int i; for (i = statements.length - 1; i >= 0 && statements[i] instanceof GrBreakStatement; i--) {} for (int j = 0; j < statements.length; j++) { GrStatement statement = statements[j]; statement.accept(this); if (j == i) handlePossibleReturn(statement); } if (myHead != null) { addPendingEdge(caseSection, myHead); } }
private static boolean containsAllCases(GrSwitchStatement statement) { final GrCaseSection[] sections = statement.getCaseSections(); for (GrCaseSection section : sections) { if (section.isDefault()) return true; } final GrExpression condition = statement.getCondition(); if (!(condition instanceof GrReferenceExpression)) return false; PsiType type = TypesUtil.unboxPrimitiveTypeWrapper(getNominalTypeNoRecursion(condition)); if (type == null) return false; if (type instanceof PsiPrimitiveType) { if (type == PsiType.BOOLEAN) return sections.length == 2; if (type == PsiType.BYTE || type == PsiType.CHAR) return sections.length == 128; return false; } if (type instanceof PsiClassType) { final PsiClass resolved = ((PsiClassType) type).resolve(); if (resolved != null && resolved.isEnum()) { int enumConstantCount = 0; final PsiField[] fields = resolved.getFields(); for (PsiField field : fields) { if (field instanceof PsiEnumConstant) enumConstantCount++; } if (sections.length == enumConstantCount) return true; } } return false; }
public void visitSwitchStatement(GrSwitchStatement switchStatement) { final GrCondition condition = switchStatement.getCondition(); if (condition != null) { condition.accept(this); } final InstructionImpl instruction = startNode(switchStatement); final GrCaseSection[] sections = switchStatement.getCaseSections(); if (!containsAllCases(switchStatement)) { addPendingEdge(switchStatement, instruction); } for (GrCaseSection section : sections) { myHead = instruction; section.accept(this); } finishNode(instruction); }
@Override public void visitSwitchStatement(GrSwitchStatement switchStatement) { final GrCaseSection[] sections = switchStatement.getCaseSections(); List<PsiType> types = new ArrayList<PsiType>(sections.length); for (GrCaseSection section : sections) { final GrExpression value = section.getCaseLabel().getValue(); final PsiType type = value != null ? value.getType() : null; if (type != null) types.add(type); } final PsiType upperBoundNullable = TypesUtil.getLeastUpperBoundNullable(types, switchStatement.getManager()); if (upperBoundNullable == null) return; myResult = new TypeConstraint[] {SubtypeConstraint.create(upperBoundNullable)}; }
private static boolean isLastStatementInCaseSection( GrCaseSection caseSection, GrSwitchStatement switchStatement) { final GrCaseSection[] sections = switchStatement.getCaseSections(); final int i = ArrayUtilRt.find(sections, caseSection); if (i == sections.length - 1) { return true; } for (int j = i + 1; j < sections.length; j++) { GrCaseSection section = sections[j]; for (GrStatement statement : section.getStatements()) { if (!(statement instanceof GrBreakStatement)) { return false; } } } return true; }
private static boolean caseClausesAreEquivalent(GrCaseSection clause1, GrCaseSection clause2) { final GrCaseLabel label1 = clause1.getCaseLabel(); final GrCaseLabel label2 = clause2.getCaseLabel(); if (!expressionsAreEquivalent(label1.getValue(), label2.getValue())) { return false; } final GrStatement[] statements1 = clause1.getStatements(); final GrStatement[] statements2 = clause2.getStatements(); if (statements1.length != statements2.length) { return false; } for (int i = 0; i < statements1.length; i++) { if (!statementsAreEquivalent(statements1[i], statements2[i])) { return false; } } return false; }