diff --git a/src/main/java/org/openrewrite/staticanalysis/ExplicitLambdaArgumentTypes.java b/src/main/java/org/openrewrite/staticanalysis/ExplicitLambdaArgumentTypes.java index b9b3c9109..c7b927f0b 100644 --- a/src/main/java/org/openrewrite/staticanalysis/ExplicitLambdaArgumentTypes.java +++ b/src/main/java/org/openrewrite/staticanalysis/ExplicitLambdaArgumentTypes.java @@ -47,195 +47,193 @@ public class ExplicitLambdaArgumentTypes extends Recipe { @Override public TreeVisitor getVisitor() { - return new ExplicitLambdaArgumentTypesVisitor(); - } - - private static class ExplicitLambdaArgumentTypesVisitor extends JavaIsoVisitor { + return new JavaIsoVisitor() { - @Override - public J.Lambda visitLambda(J.Lambda lambda, ExecutionContext ctx) { - - J.Lambda l = super.visitLambda(lambda, ctx); - if (l.getParameters().getParameters().size() <= 2 && !(l.getBody() instanceof J.Block)) { - return l; - } + @Override + public J.Lambda visitLambda(J.Lambda lambda, ExecutionContext ctx) { - J.Lambda after = l.withParameters( - l.getParameters().withParameters( - ListUtils.map(l.getParameters().getParameters(), parameter -> { - if (parameter instanceof J.VariableDeclarations) { - return maybeAddTypeExpression((J.VariableDeclarations) parameter); - } - return parameter; - }) - ) - ); - - if (after != l) { - after = after.withParameters(after.getParameters().withParenthesized(true)); - } - return after; - } - - private J.VariableDeclarations maybeAddTypeExpression(J.VariableDeclarations multiVariable) { - // if the type expression is null, it implies the types on the lambda arguments are implicit. - if (multiVariable.getTypeExpression() == null) { - J.VariableDeclarations.NamedVariable nv = multiVariable.getVariables().get(0); - TypeTree typeExpression = buildTypeTree(nv.getType(), Space.EMPTY); - if (typeExpression != null) { - // "? extends Foo" is not a valid type definition on its own. Unwrap wildcard and replace with its bound - if (typeExpression instanceof J.Wildcard) { - J.Wildcard wildcard = (J.Wildcard) typeExpression; - if (wildcard.getBoundedType() == null) { - return multiVariable; - } - typeExpression = buildTypeTree(wildcard.getBoundedType().getType(), Space.EMPTY); - } - multiVariable = multiVariable.withTypeExpression(typeExpression); - multiVariable = multiVariable.withVariables(ListUtils.map(multiVariable.getVariables(), (index, variable) -> { - if (index == 0) { - return variable.withPrefix(variable.getPrefix().withWhitespace(" ")); - } - return variable; - })); + J.Lambda l = super.visitLambda(lambda, ctx); + if (l.getParameters().getParameters().size() <= 2 && !(l.getBody() instanceof J.Block)) { + return l; } - } - return multiVariable; - } - private @Nullable TypeTree buildTypeTree(@Nullable JavaType type, Space space) { - if (type == null || type instanceof JavaType.Unknown) { - return null; - } - if (type instanceof JavaType.Primitive) { - return new J.Primitive( - Tree.randomId(), - space, - Markers.EMPTY, - (JavaType.Primitive) type + J.Lambda after = l.withParameters( + l.getParameters().withParameters( + ListUtils.map(l.getParameters().getParameters(), parameter -> { + if (parameter instanceof J.VariableDeclarations) { + return maybeAddTypeExpression((J.VariableDeclarations) parameter); + } + return parameter; + }) + ) ); - } - if (type instanceof JavaType.FullyQualified) { - - JavaType.FullyQualified fq = (JavaType.FullyQualified) type; - J.Identifier identifier = new J.Identifier(Tree.randomId(), - space, - Markers.EMPTY, - emptyList(), - fq.getClassName(), - type instanceof JavaType.Parameterized ? ((JavaType.Parameterized) type).getType() : type, - null - ); + if (after != l) { + after = after.withParameters(after.getParameters().withParenthesized(true)); + } + return after; + } - if (!fq.getTypeParameters().isEmpty()) { - JContainer typeParameters = buildTypeParameters(fq.getTypeParameters()); - if (typeParameters == null) { - //If there is a problem resolving one of the type parameters, then do not return a type - //expression for the fully-qualified type. - return null; + private J.VariableDeclarations maybeAddTypeExpression(J.VariableDeclarations multiVariable) { + // if the type expression is null, it implies the types on the lambda arguments are implicit. + if (multiVariable.getTypeExpression() == null) { + J.VariableDeclarations.NamedVariable nv = multiVariable.getVariables().get(0); + TypeTree typeExpression = buildTypeTree(nv.getType(), Space.EMPTY); + if (typeExpression != null) { + // "? extends Foo" is not a valid type definition on its own. Unwrap wildcard and replace with its bound + if (typeExpression instanceof J.Wildcard) { + J.Wildcard wildcard = (J.Wildcard) typeExpression; + if (wildcard.getBoundedType() == null) { + return multiVariable; + } + typeExpression = buildTypeTree(wildcard.getBoundedType().getType(), Space.EMPTY); + } + multiVariable = multiVariable.withTypeExpression(typeExpression); + multiVariable = multiVariable.withVariables(ListUtils.map(multiVariable.getVariables(), (index, variable) -> { + if (index == 0) { + return variable.withPrefix(variable.getPrefix().withWhitespace(" ")); + } + return variable; + })); } - return new J.ParameterizedType( - Tree.randomId(), - space, - Markers.EMPTY, - identifier, - typeParameters, - new JavaType.Parameterized(null, fq, fq.getTypeParameters()) - ); - } - maybeAddImport(fq); - return identifier; + return multiVariable; } - if (type instanceof JavaType.Array) { - JavaType.Array arrayType = (JavaType.Array) type; - // Get the base element type - JavaType elemType = arrayType.getElemType(); - while (elemType instanceof JavaType.Array) { - elemType = ((JavaType.Array) elemType).getElemType(); - } - // Build the base type expression - TypeTree result = buildTypeTree(elemType, space); - if (result == null) { + private @Nullable TypeTree buildTypeTree(@Nullable JavaType type, Space space) { + if (type == null || type instanceof JavaType.Unknown) { return null; } - - // Count dimensions and build array type - JavaType currentType = type; - while (currentType instanceof JavaType.Array) { - result = new J.ArrayType( + if (type instanceof JavaType.Primitive) { + return new J.Primitive( Tree.randomId(), - Space.EMPTY, + space, Markers.EMPTY, - result, - null, - new JLeftPadded<>(Space.EMPTY, Space.EMPTY, Markers.EMPTY), - currentType + (JavaType.Primitive) type ); - currentType = ((JavaType.Array) currentType).getElemType(); } - return result; - } - if (type instanceof JavaType.Variable) { - return buildTypeTree(((JavaType.Variable) type).getType(), space); - } - if (type instanceof JavaType.GenericTypeVariable) { - JavaType.GenericTypeVariable genericType = (JavaType.GenericTypeVariable) type; + if (type instanceof JavaType.FullyQualified) { + + JavaType.FullyQualified fq = (JavaType.FullyQualified) type; - if (!"?".equals(genericType.getName())) { - return new J.Identifier(Tree.randomId(), + J.Identifier identifier = new J.Identifier(Tree.randomId(), space, Markers.EMPTY, emptyList(), - genericType.getName(), - type, + fq.getClassName(), + type instanceof JavaType.Parameterized ? ((JavaType.Parameterized) type).getType() : type, null ); + + if (!fq.getTypeParameters().isEmpty()) { + JContainer typeParameters = buildTypeParameters(fq.getTypeParameters()); + if (typeParameters == null) { + //If there is a problem resolving one of the type parameters, then do not return a type + //expression for the fully-qualified type. + return null; + } + return new J.ParameterizedType( + Tree.randomId(), + space, + Markers.EMPTY, + identifier, + typeParameters, + new JavaType.Parameterized(null, fq, fq.getTypeParameters()) + ); + + } + maybeAddImport(fq); + return identifier; } - JLeftPadded bound = null; - NameTree boundedType = null; - if (genericType.getVariance() == JavaType.GenericTypeVariable.Variance.COVARIANT) { - bound = new JLeftPadded<>(Space.format(" "), J.Wildcard.Bound.Extends, Markers.EMPTY); - } else if (genericType.getVariance() == JavaType.GenericTypeVariable.Variance.CONTRAVARIANT) { - bound = new JLeftPadded<>(Space.format(" "), J.Wildcard.Bound.Super, Markers.EMPTY); - } + if (type instanceof JavaType.Array) { + JavaType.Array arrayType = (JavaType.Array) type; + // Get the base element type + JavaType elemType = arrayType.getElemType(); + while (elemType instanceof JavaType.Array) { + elemType = ((JavaType.Array) elemType).getElemType(); + } - if (!genericType.getBounds().isEmpty()) { - boundedType = buildTypeTree(genericType.getBounds().get(0), Space.format(" ")); - if (boundedType == null) { + // Build the base type expression + TypeTree result = buildTypeTree(elemType, space); + if (result == null) { return null; } + + // Count dimensions and build array type + JavaType currentType = type; + while (currentType instanceof JavaType.Array) { + result = new J.ArrayType( + Tree.randomId(), + Space.EMPTY, + Markers.EMPTY, + result, + null, + new JLeftPadded<>(Space.EMPTY, Space.EMPTY, Markers.EMPTY), + currentType + ); + currentType = ((JavaType.Array) currentType).getElemType(); + } + return result; + } + if (type instanceof JavaType.Variable) { + return buildTypeTree(((JavaType.Variable) type).getType(), space); } + if (type instanceof JavaType.GenericTypeVariable) { + JavaType.GenericTypeVariable genericType = (JavaType.GenericTypeVariable) type; + + if (!"?".equals(genericType.getName())) { + return new J.Identifier(Tree.randomId(), + space, + Markers.EMPTY, + emptyList(), + genericType.getName(), + type, + null + ); + } + JLeftPadded bound = null; + NameTree boundedType = null; + if (genericType.getVariance() == JavaType.GenericTypeVariable.Variance.COVARIANT) { + bound = new JLeftPadded<>(Space.format(" "), J.Wildcard.Bound.Extends, Markers.EMPTY); + } else if (genericType.getVariance() == JavaType.GenericTypeVariable.Variance.CONTRAVARIANT) { + bound = new JLeftPadded<>(Space.format(" "), J.Wildcard.Bound.Super, Markers.EMPTY); + } - return new J.Wildcard( - Tree.randomId(), - space, - Markers.EMPTY, - bound, - boundedType - ); + if (!genericType.getBounds().isEmpty()) { + boundedType = buildTypeTree(genericType.getBounds().get(0), Space.format(" ")); + if (boundedType == null) { + return null; + } + } + + return new J.Wildcard( + Tree.randomId(), + space, + Markers.EMPTY, + bound, + boundedType + ); + } + return null; } - return null; - } - private @Nullable JContainer buildTypeParameters(List typeParameters) { - List> typeExpressions = new ArrayList<>(); + private @Nullable JContainer buildTypeParameters(List typeParameters) { + List> typeExpressions = new ArrayList<>(); - for (JavaType type : typeParameters) { - Expression typeParameterExpression = (Expression) buildTypeTree(type, Space.EMPTY); - if (typeParameterExpression == null) { - return null; + for (JavaType type : typeParameters) { + Expression typeParameterExpression = (Expression) buildTypeTree(type, Space.EMPTY); + if (typeParameterExpression == null) { + return null; + } + typeExpressions.add(new JRightPadded<>( + typeParameterExpression, + Space.EMPTY, + Markers.EMPTY + )); } - typeExpressions.add(new JRightPadded<>( - typeParameterExpression, - Space.EMPTY, - Markers.EMPTY - )); + return JContainer.build(Space.EMPTY, typeExpressions, Markers.EMPTY); } - return JContainer.build(Space.EMPTY, typeExpressions, Markers.EMPTY); - } + }; } } diff --git a/src/main/java/org/openrewrite/staticanalysis/NeedBraces.java b/src/main/java/org/openrewrite/staticanalysis/NeedBraces.java index b7efe8e5d..f0df26a1a 100644 --- a/src/main/java/org/openrewrite/staticanalysis/NeedBraces.java +++ b/src/main/java/org/openrewrite/staticanalysis/NeedBraces.java @@ -59,225 +59,223 @@ public class NeedBraces extends Recipe { @Override public TreeVisitor getVisitor() { - return new NeedBracesVisitor(); - } - - private static class NeedBracesVisitor extends JavaIsoVisitor { + return new JavaIsoVisitor() { - @SuppressWarnings("NotNullFieldNotInitialized") - NeedBracesStyle needBracesStyle; + @SuppressWarnings("NotNullFieldNotInitialized") + NeedBracesStyle needBracesStyle; - /** - * A {@link J.Block} implies the section of code is implicitly surrounded in braces. - * We can use that to our advantage by saying if you aren't a block (e.g. a single {@link Statement}, etc.), - * then we're going to make this into a block. That's how we'll get the code bodies surrounded in braces. - */ - private J.Block buildBlock(T element) { - J rootElement = null; - Space end = Space.EMPTY; + /** + * A {@link J.Block} implies the section of code is implicitly surrounded in braces. + * We can use that to our advantage by saying if you aren't a block (e.g. a single {@link Statement}, etc.), + * then we're going to make this into a block. That's how we'll get the code bodies surrounded in braces. + */ + private J.Block buildBlock(T element) { + J rootElement = null; + Space end = Space.EMPTY; - Cursor currentCursor = getCursor(); - while ( - currentCursor != null && - currentCursor.getParent() != null && - !(currentCursor.getParent().getValue() instanceof J.Block) - ) { - currentCursor = currentCursor.getParent(); - } + Cursor currentCursor = getCursor(); + while ( + currentCursor != null && + currentCursor.getParent() != null && + !(currentCursor.getParent().getValue() instanceof J.Block) + ) { + currentCursor = currentCursor.getParent(); + } - if (currentCursor != null && currentCursor.getValue() instanceof JRightPadded) { - JRightPadded paddedIf = currentCursor.getValue(); - rootElement = paddedIf.getElement(); - } + if (currentCursor != null && currentCursor.getValue() instanceof JRightPadded) { + JRightPadded paddedIf = currentCursor.getValue(); + rootElement = paddedIf.getElement(); + } - // Move comments - if (rootElement instanceof Statement && !(rootElement instanceof J.DoWhileLoop)) { - Cursor blockParentCursor = currentCursor.getParent(); - J.Block block = blockParentCursor.getValue(); - List statements = block.getStatements(); - int currentIndex = statements.indexOf(rootElement); - boolean last = currentIndex == statements.size() - 1; - Space trailingComment = last ? block.getEnd() : statements.get(currentIndex + 1).getPrefix(); + // Move comments + if (rootElement instanceof Statement && !(rootElement instanceof J.DoWhileLoop)) { + Cursor blockParentCursor = currentCursor.getParent(); + J.Block block = blockParentCursor.getValue(); + List statements = block.getStatements(); + int currentIndex = statements.indexOf(rootElement); + boolean last = currentIndex == statements.size() - 1; + Space trailingComment = last ? block.getEnd() : statements.get(currentIndex + 1).getPrefix(); - if (!trailingComment.isEmpty() && !trailingComment.getWhitespace().contains("\n")) { - end = trailingComment; - if (last) { - blockParentCursor.putMessage("removeEndComments", true); - } else { - blockParentCursor.>computeMessageIfAbsent("replaced", k -> new ArrayList<>()).add(currentIndex); + if (!trailingComment.isEmpty() && !trailingComment.getWhitespace().contains("\n")) { + end = trailingComment; + if (last) { + blockParentCursor.putMessage("removeEndComments", true); + } else { + blockParentCursor.>computeMessageIfAbsent("replaced", k -> new ArrayList<>()).add(currentIndex); + } } } - } - return new J.Block( - Tree.randomId(), - Space.EMPTY, - Markers.EMPTY, - JRightPadded.build(false), - element instanceof J.Empty ? emptyList() : singletonList(JRightPadded.build(element)), - end - ); - } + return new J.Block( + Tree.randomId(), + Space.EMPTY, + Markers.EMPTY, + JRightPadded.build(false), + element instanceof J.Empty ? emptyList() : singletonList(JRightPadded.build(element)), + end + ); + } - @Override - public @Nullable J visit(@Nullable Tree tree, ExecutionContext ctx) { - if (tree instanceof SourceFile) { - SourceFile cu = (SourceFile) requireNonNull(tree); - // Python don't need none of your curly braces - if (cu.getSourcePath().toString().endsWith(".py")) { - return (J) tree; + @Override + public @Nullable J visit(@Nullable Tree tree, ExecutionContext ctx) { + if (tree instanceof SourceFile) { + SourceFile cu = (SourceFile) requireNonNull(tree); + // Python don't need none of your curly braces + if (cu.getSourcePath().toString().endsWith(".py")) { + return (J) tree; + } + needBracesStyle = Style.from(NeedBracesStyle.class, cu, Checkstyle::needBracesStyle); } - needBracesStyle = Style.from(NeedBracesStyle.class, cu, Checkstyle::needBracesStyle); + return super.visit(tree, ctx); } - return super.visit(tree, ctx); - } - @Override - public J.Block visitBlock(J.Block block, ExecutionContext ctx) { - J.Block bl = super.visitBlock(block, ctx); - if (Boolean.TRUE.equals(getCursor().pollMessage("removeEndComments"))) { - bl = bl.withEnd(bl.getEnd().withComments(emptyList())); - bl = maybeAutoFormat(block, bl, ctx); - } - List indexes = getCursor().pollMessage("replaced"); - if (indexes != null) { - for (int index : indexes) { - boolean last = index == bl.getPadding().getStatements().size() - 1; - if (!last) { - bl = bl.withStatements(ListUtils.map(bl.getStatements(), (i, stmt) -> { - if (i == index + 1) { - return stmt.withPrefix(Space.EMPTY); - } - return stmt; - })); - } else { - bl = bl.withEnd(bl.getEnd().withComments(emptyList())); + @Override + public J.Block visitBlock(J.Block block, ExecutionContext ctx) { + J.Block bl = super.visitBlock(block, ctx); + if (Boolean.TRUE.equals(getCursor().pollMessage("removeEndComments"))) { + bl = bl.withEnd(bl.getEnd().withComments(emptyList())); + bl = maybeAutoFormat(block, bl, ctx); + } + List indexes = getCursor().pollMessage("replaced"); + if (indexes != null) { + for (int index : indexes) { + boolean last = index == bl.getPadding().getStatements().size() - 1; + if (!last) { + bl = bl.withStatements(ListUtils.map(bl.getStatements(), (i, stmt) -> { + if (i == index + 1) { + return stmt.withPrefix(Space.EMPTY); + } + return stmt; + })); + } else { + bl = bl.withEnd(bl.getEnd().withComments(emptyList())); + } } + bl = maybeAutoFormat(block, bl, ctx); } - bl = maybeAutoFormat(block, bl, ctx); + return bl; } - return bl; - } - @Override - public J.If visitIf(J.If iff, ExecutionContext ctx) { - if (usedAsExpression()) { - // Kotlin has no dedicated ternary operator - return iff; - } - J.If elem = super.visitIf(iff, ctx); - boolean hasAllowableBodyType = elem.getThenPart() instanceof J.Block; - if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { - J.Block b; - if (elem.getElsePart() != null && !elem.getElsePart().getPrefix().getComments().isEmpty()) { - Space end = elem.getElsePart().getPrefix(); - elem = elem.withElsePart(elem.getElsePart().withPrefix(Space.EMPTY)); - b = buildBlock(elem.getThenPart()).withEnd(end); - } else { - b = buildBlock(elem.getThenPart()); + @Override + public J.If visitIf(J.If iff, ExecutionContext ctx) { + if (usedAsExpression()) { + // Kotlin has no dedicated ternary operator + return iff; } + J.If elem = super.visitIf(iff, ctx); + boolean hasAllowableBodyType = elem.getThenPart() instanceof J.Block; + if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { + J.Block b; + if (elem.getElsePart() != null && !elem.getElsePart().getPrefix().getComments().isEmpty()) { + Space end = elem.getElsePart().getPrefix(); + elem = elem.withElsePart(elem.getElsePart().withPrefix(Space.EMPTY)); + b = buildBlock(elem.getThenPart()).withEnd(end); + } else { + b = buildBlock(elem.getThenPart()); + } - elem = maybeAutoFormat(elem, elem.withThenPart(b), ctx); + elem = maybeAutoFormat(elem, elem.withThenPart(b), ctx); + } + return elem; } - return elem; - } - private boolean usedAsExpression() { - return getCursor().getParentOrThrow().getValue() instanceof K.StatementExpression; - } + private boolean usedAsExpression() { + return getCursor().getParentOrThrow().getValue() instanceof K.StatementExpression; + } - @Override - public J.If.Else visitElse(J.If.Else else_, ExecutionContext ctx) { - J.If.Else elem = super.visitElse(else_, ctx); - boolean hasAllowableBodyType = elem.getBody() instanceof J.Block || elem.getBody() instanceof J.If; - if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { - Space prefix = elem.getPrefix(); - Statement body = elem.getBody(); + @Override + public J.If.Else visitElse(J.If.Else else_, ExecutionContext ctx) { + J.If.Else elem = super.visitElse(else_, ctx); + boolean hasAllowableBodyType = elem.getBody() instanceof J.Block || elem.getBody() instanceof J.If; + if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { + Space prefix = elem.getPrefix(); + Statement body = elem.getBody(); - if (!prefix.getComments().isEmpty() && prefix.getWhitespace().contains("\n")) { - body = body.withPrefix(prefix); - elem = elem.withPrefix(Space.EMPTY); - } + if (!prefix.getComments().isEmpty() && prefix.getWhitespace().contains("\n")) { + body = body.withPrefix(prefix); + elem = elem.withPrefix(Space.EMPTY); + } - J.Block b = buildBlock(body); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + J.Block b = buildBlock(body); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } + return elem; } - return elem; - } - @Override - public J.WhileLoop visitWhileLoop(J.WhileLoop whileLoop, ExecutionContext ctx) { - J.WhileLoop elem = super.visitWhileLoop(whileLoop, ctx); - boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? - elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : - elem.getBody() instanceof J.Block; - if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { - J.Block b = buildBlock(elem.getBody()); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); - } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { - J.Block b = buildBlock(elem.getBody()); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + @Override + public J.WhileLoop visitWhileLoop(J.WhileLoop whileLoop, ExecutionContext ctx) { + J.WhileLoop elem = super.visitWhileLoop(whileLoop, ctx); + boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? + elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : + elem.getBody() instanceof J.Block; + if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { + J.Block b = buildBlock(elem.getBody()); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { + J.Block b = buildBlock(elem.getBody()); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } + return elem; } - return elem; - } - @Override - public J.DoWhileLoop visitDoWhileLoop(J.DoWhileLoop doWhileLoop, ExecutionContext ctx) { - J.DoWhileLoop elem = super.visitDoWhileLoop(doWhileLoop, ctx); - boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? - elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : - elem.getBody() instanceof J.Block; - if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { - J.Block b = buildBlock(elem.getBody()); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); - } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { - // The trailing comment between the body and the `while` keyword lives in the - // `before` space of the `whileCondition`. When wrapping the body in a block, - // move a same-line trailing comment into the new block's end so it stays with - // the body statement rather than drifting onto the closing brace. - JLeftPadded> whileCondition = elem.getPadding().getWhileCondition(); - Space whileBefore = whileCondition.getBefore(); - Space end = Space.EMPTY; - if (!whileBefore.getComments().isEmpty() && !whileBefore.getWhitespace().contains("\n")) { - end = whileBefore; - elem = elem.getPadding().withWhileCondition(whileCondition.withBefore(Space.SINGLE_SPACE)); + @Override + public J.DoWhileLoop visitDoWhileLoop(J.DoWhileLoop doWhileLoop, ExecutionContext ctx) { + J.DoWhileLoop elem = super.visitDoWhileLoop(doWhileLoop, ctx); + boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? + elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : + elem.getBody() instanceof J.Block; + if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { + J.Block b = buildBlock(elem.getBody()); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { + // The trailing comment between the body and the `while` keyword lives in the + // `before` space of the `whileCondition`. When wrapping the body in a block, + // move a same-line trailing comment into the new block's end so it stays with + // the body statement rather than drifting onto the closing brace. + JLeftPadded> whileCondition = elem.getPadding().getWhileCondition(); + Space whileBefore = whileCondition.getBefore(); + Space end = Space.EMPTY; + if (!whileBefore.getComments().isEmpty() && !whileBefore.getWhitespace().contains("\n")) { + end = whileBefore; + elem = elem.getPadding().withWhileCondition(whileCondition.withBefore(Space.SINGLE_SPACE)); + } + J.Block b = buildBlock(elem.getBody()).withEnd(end); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); } - J.Block b = buildBlock(elem.getBody()).withEnd(end); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + return elem; } - return elem; - } - @Override - public J.ForLoop visitForLoop(J.ForLoop forLoop, ExecutionContext ctx) { - J.ForLoop elem = super.visitForLoop(forLoop, ctx); - boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? - elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : - elem.getBody() instanceof J.Block; - if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { - J.Block b = buildBlock(elem.getBody()); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); - } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { - J.Block b = buildBlock(elem.getBody()); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + @Override + public J.ForLoop visitForLoop(J.ForLoop forLoop, ExecutionContext ctx) { + J.ForLoop elem = super.visitForLoop(forLoop, ctx); + boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? + elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : + elem.getBody() instanceof J.Block; + if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { + J.Block b = buildBlock(elem.getBody()); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { + J.Block b = buildBlock(elem.getBody()); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } + return elem; } - return elem; - } - @Override - public J.ForEachLoop visitForEachLoop(J.ForEachLoop forEachLoop, ExecutionContext ctx) { - J.ForEachLoop elem = super.visitForEachLoop(forEachLoop, ctx); - boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? - elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : - elem.getBody() instanceof J.Block; - if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { - J.Block b = buildBlock(elem.getBody()); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); - } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { - J.Block b = buildBlock(elem.getBody()); - elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + @Override + public J.ForEachLoop visitForEachLoop(J.ForEachLoop forEachLoop, ExecutionContext ctx) { + J.ForEachLoop elem = super.visitForEachLoop(forEachLoop, ctx); + boolean hasAllowableBodyType = needBracesStyle.getAllowEmptyLoopBody() ? + elem.getBody() instanceof J.Block || elem.getBody() instanceof J.Empty : + elem.getBody() instanceof J.Block; + if (!needBracesStyle.getAllowEmptyLoopBody() && elem.getBody() instanceof J.Empty) { + J.Block b = buildBlock(elem.getBody()); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } else if (!needBracesStyle.getAllowSingleLineStatement() && !hasAllowableBodyType) { + J.Block b = buildBlock(elem.getBody()); + elem = maybeAutoFormat(elem, elem.withBody(b), ctx); + } + return elem; } - return elem; - } + }; } } diff --git a/src/main/java/org/openrewrite/staticanalysis/RemoveToStringCallsFromArrayInstances.java b/src/main/java/org/openrewrite/staticanalysis/RemoveToStringCallsFromArrayInstances.java index de4257ddf..8c61352cf 100644 --- a/src/main/java/org/openrewrite/staticanalysis/RemoveToStringCallsFromArrayInstances.java +++ b/src/main/java/org/openrewrite/staticanalysis/RemoveToStringCallsFromArrayInstances.java @@ -62,87 +62,85 @@ public class RemoveToStringCallsFromArrayInstances extends Recipe { @Override public TreeVisitor getVisitor() { - return new RemoveToStringFromArraysVisitor(); - } - - private static class RemoveToStringFromArraysVisitor extends JavaVisitor { - @Override - public J visitMethodInvocation(J.MethodInvocation mi, ExecutionContext ctx) { - if (TOSTRING_MATCHER.matches(mi)) { - Expression select = mi.getSelect(); - if (select == null) { - return mi; - } + return new JavaVisitor() { + @Override + public J visitMethodInvocation(J.MethodInvocation mi, ExecutionContext ctx) { + if (TOSTRING_MATCHER.matches(mi)) { + Expression select = mi.getSelect(); + if (select == null) { + return mi; + } - return buildReplacement(select, mi); - } - if (METHOD_MATCHERS.stream().anyMatch(matcher -> matcher.matches(mi))) { - // deals with edge cases where .toString() is called implicitly - JavaType.Method methodType = mi.getMethodType(); - if (methodType == null) { - return mi; + return buildReplacement(select, mi); } - List parameterTypes = methodType.getParameterTypes(); - List arguments = mi.getArguments(); - for (int i = 0; i < arguments.size(); i++) { - Expression arg = arguments.get(i); - if (arg.getType() instanceof JavaType.Array && - (i > parameterTypes.size() - 1 || - !(parameterTypes.get(i) instanceof JavaType.Array))) { - getCursor().putMessage("METHOD_KEY", mi); - break; + if (METHOD_MATCHERS.stream().anyMatch(matcher -> matcher.matches(mi))) { + // deals with edge cases where .toString() is called implicitly + JavaType.Method methodType = mi.getMethodType(); + if (methodType == null) { + return mi; + } + List parameterTypes = methodType.getParameterTypes(); + List arguments = mi.getArguments(); + for (int i = 0; i < arguments.size(); i++) { + Expression arg = arguments.get(i); + if (arg.getType() instanceof JavaType.Array && + (i > parameterTypes.size() - 1 || + !(parameterTypes.get(i) instanceof JavaType.Array))) { + getCursor().putMessage("METHOD_KEY", mi); + break; + } } + } else if (OBJECTS_TOSTRING_MATCHER.matches(mi) || VALUEOF_MATCHER.matches(mi)) { + // method is static + Expression select = mi.getArguments().get(0); + maybeRemoveImport("java.util.Objects"); + + return buildReplacement(select, mi); } - } else if (OBJECTS_TOSTRING_MATCHER.matches(mi) || VALUEOF_MATCHER.matches(mi)) { - // method is static - Expression select = mi.getArguments().get(0); - maybeRemoveImport("java.util.Objects"); - return buildReplacement(select, mi); + return super.visitMethodInvocation(mi, ctx); } - return super.visitMethodInvocation(mi, ctx); - } + public J buildReplacement(Expression select, J.MethodInvocation mi) { + if (!(select.getType() instanceof JavaType.Array)) { + return mi; + } - public J buildReplacement(Expression select, J.MethodInvocation mi) { - if (!(select.getType() instanceof JavaType.Array)) { - return mi; + maybeAddImport("java.util.Arrays"); + return JavaTemplate.builder("Arrays.toString(#{anyArray(java.lang.Object)})") + .imports("java.util.Arrays") + .build() + .apply(getCursor(), mi.getCoordinates().replace(), select); } - maybeAddImport("java.util.Arrays"); - return JavaTemplate.builder("Arrays.toString(#{anyArray(java.lang.Object)})") - .imports("java.util.Arrays") - .build() - .apply(getCursor(), mi.getCoordinates().replace(), select); - } - - @Override - public Expression visitExpression(Expression exp, ExecutionContext ctx) { - Expression e = (Expression) super.visitExpression(exp, ctx); - if (e instanceof TypedTree && e.getType() instanceof JavaType.Array) { - Cursor c = getCursor().dropParentWhile(is -> is instanceof J.Parentheses || !(is instanceof Tree)); - if (c.getMessage("METHOD_KEY") != null || c.getMessage("BINARY_FOUND") != null) { - maybeAddImport("java.util.Arrays"); - return JavaTemplate.builder("Arrays.toString(#{anyArray(java.lang.Object)})") - .imports("java.util.Arrays") - .build() - .apply(getCursor(), e.getCoordinates().replace(), e); + @Override + public Expression visitExpression(Expression exp, ExecutionContext ctx) { + Expression e = (Expression) super.visitExpression(exp, ctx); + if (e instanceof TypedTree && e.getType() instanceof JavaType.Array) { + Cursor c = getCursor().dropParentWhile(is -> is instanceof J.Parentheses || !(is instanceof Tree)); + if (c.getMessage("METHOD_KEY") != null || c.getMessage("BINARY_FOUND") != null) { + maybeAddImport("java.util.Arrays"); + return JavaTemplate.builder("Arrays.toString(#{anyArray(java.lang.Object)})") + .imports("java.util.Arrays") + .build() + .apply(getCursor(), e.getCoordinates().replace(), e); + } } + + return e; } - return e; - } + @Override + public J.Binary visitBinary(J.Binary binary, ExecutionContext ctx) { + Expression left = binary.getLeft(); + Expression right = binary.getRight(); - @Override - public J.Binary visitBinary(J.Binary binary, ExecutionContext ctx) { - Expression left = binary.getLeft(); - Expression right = binary.getRight(); + if (binary.getOperator() == J.Binary.Type.Addition && (left.getType() instanceof JavaType.Array || right.getType() instanceof JavaType.Array)) { + getCursor().putMessage("BINARY_FOUND", binary); + } - if (binary.getOperator() == J.Binary.Type.Addition && (left.getType() instanceof JavaType.Array || right.getType() instanceof JavaType.Array)) { - getCursor().putMessage("BINARY_FOUND", binary); + return (J.Binary) super.visitBinary(binary, ctx); } - - return (J.Binary) super.visitBinary(binary, ctx); - } + }; } }