All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrewrite.staticanalysis.DefaultComesLastVisitor Maven / Gradle / Ivy

/*
 * Copyright 2020 the original author or authors.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* https://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openrewrite.staticanalysis; import lombok.EqualsAndHashCode; import lombok.Value; import org.openrewrite.Tree; import org.openrewrite.internal.ListUtils; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.style.DefaultComesLastStyle; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.Space; import org.openrewrite.java.tree.Statement; import org.openrewrite.marker.Markers; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @Value @EqualsAndHashCode(callSuper = false) public class DefaultComesLastVisitor

extends JavaIsoVisitor

{ DefaultComesLastStyle style; @Override public J.Switch visitSwitch(J.Switch switch_, P p) { J.Switch s = visitAndCast(switch_, p, super::visitSwitch); if (!isDefaultCaseLastOrNotPresent(switch_)) { List cases = s.getCases().getStatements().stream().map(J.Case.class::cast).collect(Collectors.toList()); List fixedCases = new ArrayList<>(cases.size()); int defaultCaseIndex = -1; J.Case defaultCase = null; for (int i = 0; i < cases.size(); i++) { J.Case aCase = cases.get(i); if (isDefaultCase(aCase)) { defaultCaseIndex = i; defaultCase = aCase; } } List casesGroupedWithDefault = new ArrayList<>(); boolean foundNonEmptyCase = false; for (int i = defaultCaseIndex - 1; i >= 0; i--) { J.Case aCase = cases.get(i); if (aCase.getStatements().isEmpty() && !foundNonEmptyCase) { casesGroupedWithDefault.add(0, aCase); } else { foundNonEmptyCase = true; fixedCases.add(0, aCase); } } foundNonEmptyCase = false; for (int i = defaultCaseIndex + 1; i < cases.size(); i++) { J.Case aCase = cases.get(i); if (defaultCase != null && defaultCase.getStatements().isEmpty() && aCase.getStatements().isEmpty() && !foundNonEmptyCase) { casesGroupedWithDefault.add(aCase); } else { if (defaultCase != null && defaultCase.getStatements().isEmpty() && !foundNonEmptyCase) { // the last case grouped with default can be non-empty. it will be flipped with // the default case, including its statements casesGroupedWithDefault.add(aCase); } foundNonEmptyCase = true; fixedCases.add(aCase); } } if (defaultCase != null && !casesGroupedWithDefault.isEmpty()) { J.Case lastGroupedWithDefault = casesGroupedWithDefault.get(casesGroupedWithDefault.size() - 1); if (!lastGroupedWithDefault.getStatements().isEmpty()) { casesGroupedWithDefault.set(casesGroupedWithDefault.size() - 1, lastGroupedWithDefault.withStatements(Collections.emptyList())); defaultCase = defaultCase.withStatements(lastGroupedWithDefault.getStatements()); } } J.Case lastNotGroupedWithDefault = fixedCases.get(fixedCases.size() - 1); if (!lastNotGroupedWithDefault.getStatements().stream().reduce((s1, s2) -> s2) .map(stat -> stat instanceof J.Break || stat instanceof J.Continue || stat instanceof J.Return || stat instanceof J.Throw) .orElse(false)) { // add a break statement since this case is now no longer last and would fall through List statementsOfCaseBeingMoved = new ArrayList<>(lastNotGroupedWithDefault.getStatements()); J.Break breakStatement = autoFormat( new J.Break(Tree.randomId(), Space.EMPTY, Markers.EMPTY, null), p ); statementsOfCaseBeingMoved.add(breakStatement); lastNotGroupedWithDefault = lastNotGroupedWithDefault.withStatements( ListUtils.map(statementsOfCaseBeingMoved, stmt -> autoFormat(stmt, p, getCursor())) ); fixedCases.set(fixedCases.size() - 1, lastNotGroupedWithDefault); } fixedCases.addAll(casesGroupedWithDefault); if (defaultCase != null) { if (defaultCase.getStatements().stream().reduce((s1, s2) -> s2) .map(stat -> stat instanceof J.Break || stat instanceof J.Continue || isVoidReturn(stat)) .orElse(false)) { List fixedDefaultStatements = new ArrayList<>(defaultCase.getStatements()); fixedDefaultStatements.remove(fixedDefaultStatements.size() - 1); fixedCases.add(defaultCase.withStatements(fixedDefaultStatements)); } else { fixedCases.add(defaultCase); } } boolean changed = true; if (cases.size() == fixedCases.size()) { changed = false; for (int i = 0; i < cases.size(); i++) { if (cases.get(i) != fixedCases.get(i)) { changed = true; break; } } } if (changed) { s = s.withCases(s.getCases().withStatements(fixedCases.stream().map(Statement.class::cast).collect(Collectors.toList()))); } } return s; } private boolean isVoidReturn(Statement stat) { return stat instanceof J.Return && ((J.Return) stat).getExpression() == null; } private boolean isDefaultCaseLastOrNotPresent(J.Switch switch_) { J.Case defaultCase = null; J.Case prior = null; for (Statement aCaseStmt : switch_.getCases().getStatements()) { if (!(aCaseStmt instanceof J.Case)) { continue; } J.Case aCase = (J.Case) aCaseStmt; if (defaultCase != null) { // default case was not last return false; } if (isDefaultCase(aCase)) { defaultCase = aCase; } if (defaultCase != null && prior != null && Boolean.TRUE.equals(style.getSkipIfLastAndSharedWithCase()) && prior.getStatements().isEmpty()) { return true; } prior = aCase; } // either default was not present or it was last return true; } private boolean isDefaultCase(J.Case case_) { Expression elem = case_.getPattern(); return elem instanceof J.Identifier && ((J.Identifier) elem).getSimpleName().equals("default"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy