Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ public J.Block visitBlock(J.Block block, ExecutionContext ctx) {
assignment.getType()
);
}

Expression remainder = extractRemainderFromLeftSpine(binary, variable);
if (remainder != null) {
return new J.AssignmentOperation(
Tree.randomId(),
assignment.getPrefix(),
assignment.getMarkers(),
variable.withPrefix(Space.EMPTY),
new JLeftPadded<>(Space.SINGLE_SPACE, J.AssignmentOperation.Type.Addition, Markers.EMPTY),
remainder.withPrefix(Space.SINGLE_SPACE),
assignment.getType()
);
}
}
}
}
Expand All @@ -102,4 +115,20 @@ public J.Block visitBlock(J.Block block, ExecutionContext ctx) {
}
};
}

private static Expression extractRemainderFromLeftSpine(J.Binary binary, Expression variable) {
Expression left = binary.getLeft();
if (left instanceof J.Binary) {
J.Binary leftBinary = (J.Binary) left;
if (leftBinary.getOperator() == J.Binary.Type.Addition || leftBinary.getOperator() == J.Binary.Type.Subtraction) {
Expression remainder = extractRemainderFromLeftSpine(leftBinary, variable);
if (remainder != null) {
return binary.withLeft(remainder);
}
}
} else if (SemanticallyEqual.areEqual(variable, left) && binary.getOperator() == J.Binary.Type.Addition) {
return binary.getRight().withPrefix(Space.EMPTY);
}
return null;
}
}
4 changes: 2 additions & 2 deletions src/main/resources/META-INF/rewrite/recipes.csv
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanaly
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.ReplaceWeekYearWithYear,Week Year (YYYY) should not be used for date formatting,"For most dates Week Year (YYYY) and Year (yyyy) yield the same results. However, on the last week of December and the first week of January, Week Year could produce unexpected results. This is a common source of off-by-one-year bugs that typically only manifest around New Year's Eve, making them difficult to catch during development and testing.",1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SillyEqualsCheck,Silly equality checks should not be made,Detects `.equals()` calls that compare incompatible types and will always return `false`. Replaces `.equals(null)` with `== null` and array `.equals()` with `Arrays.equals()`. Flags comparisons between unrelated types or between arrays and non-arrays.,1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SimplifyArraysAsList,Simplify `Arrays.asList(..)` with varargs,"Simplifies `Arrays.asList()` method calls that use explicit array creation to use varargs instead. For example, `Arrays.asList(new String[]{""a"", ""b"", ""c""})` becomes `Arrays.asList(""a"", ""b"", ""c"")`. Explicitly constructing an array to pass to a varargs parameter adds visual clutter without changing behavior, since the compiler generates the array automatically.",1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.StaticAccessViaInstance,Static members should be accessed via the class name,Accessing static fields or calling static methods on an instance reference is misleading. Static members should be accessed using the declaring class name instead.,1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SimplifyBooleanExpression,Simplify boolean expression,"Checks for overly complicated boolean expressions, such as `if (b == true)`, `b || true`, `!false`, etc. Needlessly complex boolean logic makes code harder to reason about and increases the chance of introducing errors during future modifications.",1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SimplifyBooleanExpressionWithDeMorgan,Simplify boolean expressions using De Morgan's laws,"Applies De Morgan's laws to simplify boolean expressions with negation. Transforms `!(a && b)` to `!a || !b` and `!(a || b)` to `!a && !b`. Distributing negations inward eliminates the outer `!` and makes each individual condition's polarity immediately visible, which aids comprehension.",1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SimplifyBooleanReturn,Simplify boolean return,"Simplifies Boolean expressions by removing redundancies. For example, `a && true` simplifies to `a`. Wrapping a boolean expression in an if-then-else just to return `true` or `false` adds unnecessary control flow that obscures the straightforward intent of the expression.",1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
Expand All @@ -156,6 +155,7 @@ maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanaly
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SimplifyTernaryRecipes$SimplifyTernaryTrueFalseRecipe,Replace `booleanExpression ? true : false` with `booleanExpression`,Replace ternary expressions like `booleanExpression ? true : false` with `booleanExpression`.,1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SingleLineCommentSpacing,Add space after // in single-line comments,Ensures there is exactly one space after // in single-line comments when missing.,1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.SortedSetStreamToLinkedHashSet,Sorted set stream should be collected to LinkedHashSet,Converts `set.stream().sorted().collect(Collectors.toSet())` to `set.stream().sorted().collect(LinkedHashSet::new)`.,1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.StaticAccessViaInstance,Static members should be accessed via the class name,Accessing static fields or calling static methods on an instance reference is misleading. Static members should be accessed using the declaring class name instead.,1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.StaticMethodNotFinal,Static methods need not be final,Static methods do not need to be declared final because they cannot be overridden. Redundant modifiers add noise to the code and can suggest a misunderstanding of the language's dispatch model.,1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.StringLiteralEquality,Use `String.equals()` on `String` literals,"`String.equals()` should be used when checking value equality on String literals. Using `==` or `!=` compares object references, not the actual value of the Strings. This only modifies code where at least one side of the binary operation (`==` or `!=`) is a String literal, such as `""someString"" == someVariable;`. This is to prevent inadvertently changing code where referential equality is the user's intent. Reference equality on strings is fragile because it depends on JVM string interning behavior, which can vary across runtimes and is not guaranteed for dynamically constructed strings.",1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.TernaryOperatorsShouldNotBeNested,Ternary operators should not be nested,"Nested ternary operators can be hard to read quickly. Prefer simpler constructs for improved readability. If supported, this recipe will try to replace nested ternaries with switch expressions. Deeply nested conditional expressions obscure the branching logic and make it easy to misread which value corresponds to which condition.",1,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
Expand Down Expand Up @@ -202,7 +202,7 @@ maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanaly
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.UseMapContainsKey,Use `Map#containsKey`,`map.keySet().contains(a)` can be simplified to `map.containsKey(a)`.,2,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.ReplaceApacheCommonsLang3ValidateNotNullWithObjectsRequireNonNull,Replace `org.apache.commons.lang3.Validate#notNull` with `Objects#requireNonNull`,Replace `org.apache.commons.lang3.Validate.notNull(..)` with `Objects.requireNonNull(..)`.,5,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.ReplaceValidateNotNullHavingSingleArgWithObjectsRequireNonNull,Replace `org.apache.commons.lang3.Validate#notNull` with `Objects#requireNonNull`,Replace `org.apache.commons.lang3.Validate.notNull(Object)` with `Objects.requireNonNull(Object)`.,3,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.CodeCleanup,Code cleanup,"Automatically cleanup code, e.g. remove unnecessary parentheses, simplify expressions.",26,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.CodeCleanup,Code cleanup,"Automatically cleanup code, e.g. remove unnecessary parentheses, simplify expressions.",27,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.ReplaceThreadRunWithThreadStart,Replace calls to `Thread.run()` with `Thread.start()`,`Thread.run()` should not be called directly.,2,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.CommonDeclarationSiteTypeVariances,Properly use declaration-site type variance for well-known types,"When using a method parameter like `Function<IN, OUT>`, it should rather be `Function<? super IN, ? extends OUT>`. This recipe checks for method parameters of well-known types.",2,,Static analysis and remediation,,Remediations for issues identified by SAST tools.,
maven,org.openrewrite.recipe:rewrite-static-analysis,org.openrewrite.staticanalysis.java.MoveFieldAnnotationToType,Move annotation to type instead of field,"Annotations that could be applied to either a field or a type are better applied to the type, because similar annotations may be more restrictive, leading to compile errors like 'scoping construct cannot be annotated with type-use annotation' when migrating later.",1,Java,Static analysis and remediation,,Remediations for issues identified by SAST tools.,"[{""name"":""annotationType"",""type"":""String"",""displayName"":""Annotation type"",""description"":""The type of annotation to move."",""example"":""org.openrewrite..*""}]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.Issue;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

Expand Down Expand Up @@ -205,6 +206,68 @@ void test(int i) {
);
}

@Issue("https://github.com/openrewrite/rewrite-static-analysis/issues/696")
@Test
void compoundAssignmentWithChainedAddition() {
rewriteRun(
java(
"""
class Test {
void test(int lastEnd, int startIndex, int i) {
lastEnd = lastEnd + startIndex + i + 1;
}
}
""",
"""
class Test {
void test(int lastEnd, int startIndex, int i) {
lastEnd += startIndex + i + 1;
}
}
"""
)
);
}

@Issue("https://github.com/openrewrite/rewrite-static-analysis/issues/696")
@Test
void compoundAssignmentWithChainedMixedOperators() {
rewriteRun(
java(
"""
class Test {
void test(int x, int a, int b) {
x = x + a - b;
}
}
""",
"""
class Test {
void test(int x, int a, int b) {
x += a - b;
}
}
"""
)
);
}

@Issue("https://github.com/openrewrite/rewrite-static-analysis/issues/696")
@Test
void doNotChangeChainStartingWithSubtraction() {
rewriteRun(
java(
"""
class Test {
void test(int x, int a, int b) {
x = x - a + b;
}
}
"""
)
);
}

@Test
void compoundAssignmentWithNonLiterals() {
rewriteRun(
Expand Down
Loading