Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: openrewrite/rewrite-static-analysis
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.34.1
Choose a base ref
...
head repository: openrewrite/rewrite-static-analysis
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.35.0
Choose a head ref
  • 11 commits
  • 29 files changed
  • 3 contributors

Commits on May 8, 2026

  1. Document identity-semantics caveat on `PrimitiveWrapperClassConstruct…

    …orToValueOf` (#883)
    
    `valueOf` may return cached instances, so the rewrite is not behavior-preserving
    for code that compares boxed values via reference identity, uses
    `System.identityHashCode`, or synchronizes on the boxed value.
    
    Refs #880
    timtebeek authored May 8, 2026
    Configuration menu
    Copy the full SHA
    932cca9 View commit details
    Browse the repository at this point in the history

Commits on May 13, 2026

  1. Skip FinalClass when class has anonymous inner subclasses (#886)

    A class with only private constructors can still be subclassed from within its own body via anonymous classes. Making such a class `final` produces uncompilable code.
    
    Fixes #885
    timtebeek authored May 13, 2026
    Configuration menu
    Copy the full SHA
    3f61726 View commit details
    Browse the repository at this point in the history

Commits on May 15, 2026

  1. Extend multi-constructor guard in ReplaceLambdaWithMethodReference

    …to parameterized types (#887)
    
    The guard against converting `() -> new X()` to `X::new` when `X` has
    multiple constructors only checked `JavaType.Class`, missing diamond
    expressions like `new EntityIdForRepositoryVisitor<>()` whose type is
    `JavaType.Parameterized`. The resulting `::new` could become ambiguous
    between overloaded `Supplier`/`Function` targets.
    timtebeek authored May 15, 2026
    Configuration menu
    Copy the full SHA
    0f017bd View commit details
    Browse the repository at this point in the history
  2. Preserve null cast at varargs position in RemoveRedundantTypeCast (

    …#888)
    
    A cast like `(String) null` passed as the last argument to a varargs
    method (e.g. `Method.invoke(Object, Object...)`) is required to
    disambiguate between passing `null` as the entire array and passing a
    single null element. Skip removal when the expression is a `null`
    literal at the last position whose parameter is an array.
    timtebeek authored May 15, 2026
    Configuration menu
    Copy the full SHA
    436e8c2 View commit details
    Browse the repository at this point in the history
  3. Retain explicit type arguments on no-arg static methods in `Unnecessa…

    …ryExplicitTypeArguments` (#889)
    
    When a static method declares a type parameter but takes no arguments
    (e.g. `<T> T any()`), the type parameter cannot be inferred from
    call-site arguments. The existing `shouldRetainOnStaticMethod` guard
    relied on `JavaType.Method.getDeclaredFormalTypeNames()`, which the
    parser does not always populate, so the guard would incorrectly allow
    removal and break overload/inference in the enclosing call.
    timtebeek authored May 15, 2026
    Configuration menu
    Copy the full SHA
    7bea420 View commit details
    Browse the repository at this point in the history

Commits on May 16, 2026

  1. Configuration menu
    Copy the full SHA
    5e79cd3 View commit details
    Browse the repository at this point in the history
  2. Detect overloads on parameterized receiver in hasMethodOverloading (#…

    …890)
    
    `RemoveRedundantTypeCast` was stripping `(Integer) null` from
    `property.set((Integer) null)` on a `Property<Integer>`, breaking
    compilation because `Property<T>` declares both `set(T)` and
    `set(Provider<? extends T>)`. The `hasMethodOverloading` guard missed
    this case: when the receiver is parameterized, `getDeclaringType()`
    returns a `JavaType.Parameterized`, which the `JavaType.Class` filter
    discarded. Widen to `JavaType.FullyQualified` so methods on
    parameterized receivers are inspected too.
    timtebeek authored May 16, 2026
    Configuration menu
    Copy the full SHA
    d79cdd4 View commit details
    Browse the repository at this point in the history
  3. Preserve cast on generic method invocation in overloaded outer call (#…

    …891)
    
    * Preserve cast on generic method invocation in overloaded outer call
    
    When a cast wraps a generic method invocation whose declared return is a
    type variable (e.g. `(Object) cursor.getValue()` where `<T> T getValue()`),
    the cast pins the inferred return type so an overloaded outer call like
    `StringBuilder.append` resolves unambiguously. The LST resolves the
    invocation's return to its bound (Object), so the existing
    `castType.equals(expressionType)` shortcut dropped the cast before the
    `hasMethodOverloading` check could run. Detect the generic return on the
    declaring class and preserve the cast when the parent call is overloaded.
    
    * Extract `returnsDeclaredTypeParameter` helper
    
    Dedupe the declaring-type method-loop between the new MethodCall branch
    and the existing Lambda-body branch. Also hoist the cheap
    `hasMethodOverloading` check above the loop so non-overloaded parent
    calls short-circuit without scanning the declaring type's methods.
    timtebeek authored May 16, 2026
    Configuration menu
    Copy the full SHA
    d99ed6f View commit details
    Browse the repository at this point in the history

Commits on May 18, 2026

  1. Guard cast to JavaType.Annotation in ReorderAnnotations (#894)

    `JavaType.Class#getAnnotations()` returns `List<FullyQualified>`, whose
    elements can be `JavaType.ShallowClass` rather than `JavaType.Annotation`.
    Check the runtime type before casting to avoid a `ClassCastException`
    when the `@Target` meta-annotation is only available as a shallow class.
    timtebeek authored May 18, 2026
    Configuration menu
    Copy the full SHA
    857aab2 View commit details
    Browse the repository at this point in the history
  2. Strip diamond operator from cast in UseLambdaForFunctionalInterface (

    …#893)
    
    * Strip diamond operator from cast in `UseLambdaForFunctionalInterface`
    
    The diamond operator is only valid after `new` (JLS 15.9), not in a cast
    expression (JLS 15.16). When converting `new Foo<>() {...}` to a lambda
    that required a cast, the recipe produced invalid `(Foo<>) ...`.
    
    * Rebuild cast type from resolved interface to avoid raw-type warning
    
    Instead of stripping the diamond to a raw cast like `(Foo)`, reconstruct
    the parameterized type from the resolved interface's type arguments so
    the emitted cast (e.g. `(Foo<Bar>)`) compiles without unchecked warnings.
    
    * Tighten cast-rebuild helpers in `UseLambdaForFunctionalInterface`
    
    Add `hasDiamond` helper, use static-imported `emptyList()`, and flatten
    the diamond-handling block.
    
    * Use `JRightPadded.build` and presize list in `buildTypeParameters`
    
    * Simplify `buildTypeTree` and add a multi-type-argument test
    
    The earlier port handled `Primitive`, `GenericTypeVariable`, and
    wildcards, but those branches are unreachable here: generics can't be
    primitive, and the parser collapses type variables to their bound when
    inferring a diamond's type arguments. Reduce the helper to the only
    reachable path (`FullyQualified`) and add a multi-arg test.
    
    * Drop unused `Space` param and cache `fq.getTypeParameters()`
    timtebeek authored May 18, 2026
    Configuration menu
    Copy the full SHA
    8e930b0 View commit details
    Browse the repository at this point in the history
  3. Replace var with interface type in UseLambdaForFunctionalInterface (

    #896)
    
    * Replace `var` with interface type in `UseLambdaForFunctionalInterface`
    
    A lambda is a poly expression and needs an explicit target type from
    the declaration (JLS 14.4.1, 15.27.1), but `var` borrows its type from
    the right-hand side. Converting `var x = new Foo() {...}` to a lambda
    while keeping `var` produced code that no longer compiles.
    
    When the initializer of a `var` local is converted to a lambda, replace
    the `var` token with the anonymous class's interface type. Diamonds on
    the right-hand side are expanded from the resolved lambda type so the
    emitted declaration compiles without unchecked warnings.
    
    Fixes #895
    
    * Refactor: use JavaVarKeyword marker and dedupe diamond resolution
    
    Detect `var` via the `JavaVarKeyword` marker the parser attaches, rather
    than string-comparing the identifier name — avoids tripping on a user
    identifier literally named `var`.
    
    Extract the diamond-to-resolved-type rebuild that `maybeAddCast` and the
    new `visitVariableDeclarations` share into a `resolveDiamond` helper, and
    inline the single-use `isVarType` predicate.
    
    * Return directly instead of reassigning the result
    timtebeek authored May 18, 2026
    Configuration menu
    Copy the full SHA
    03d153e View commit details
    Browse the repository at this point in the history
Loading