openrewrite / openrewrite/rewrite-static-analysis

InstanceOfPatternMatch changes code meaning with multiple reassignments

Open
#480 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Java
Stars
62
Forks
112
Avg merge
1d 19h
Merged PRs (30d)
40

Description

What version of OpenRewrite are you using?

I am using

  • Gradle plugin: v7.2.0
  • OpenRewrite: latest - 8.48.0(?)
  • rewrite-migrate-java: latest - 3.4.0(?)

How are you running OpenRewrite?

I am running Gradle in a multi-module project:

plugins {
    id 'org.openrewrite.rewrite' version '7.2.0' apply false
}

def javaProjects = subprojects - project(":release").allprojects
configure (javaProjects) {
    apply plugin: 'java'
    apply plugin: 'checkstyle'
    apply plugin: 'org.openrewrite.rewrite'

    sourceCompatibility = 21
    targetCompatibility = 21

    rewrite {
        activeRecipe("org.openrewrite.staticanalysis.InstanceOfPatternMatch")
    }

    dependencies {
        rewrite(platform("org.openrewrite.recipe:rewrite-recipe-bom:latest.release"))
        rewrite("org.openrewrite.recipe:rewrite-testing-frameworks")
        rewrite("org.openrewrite.recipe:rewrite-migrate-java")
    }

What is the smallest, simplest way to reproduce the problem?

    public static void main(String[] args) {
        Object o = -3;
        if (o instanceof Integer) {
            o = Math.abs((int) o) * 10;
            o = Math.max((int) o, 5);
        }
        System.out.println(o);
    }

What did you expect to see?

Perhaps unchanged? Regardless the code should print 30

What did you see instead?

The is modified to the following, and prints 5

    public static void main(String[] args) {
        Object o = -3;
        if (o instanceof Integer integer) {
            o = Math.abs(integer) * 10;
            o = Math.max(integer, 5);
        }
        System.out.println(o);
    }

Are you interested in contributing a fix to OpenRewrite?

Not at this stage sorry, but perhaps in the future if I become a more regular user. (From a glance at some rule implementations, the pattern matching engine indeed looks interesting and powerful!)

At this stage I'm just running some initial trials and was lucky to spot (the less simple variant of) this amongst a fairly large changeset.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the InstanceOfPatternMatch recipe and reproduce the Java example showing two reassignments inside one instanceof block. Trace how the pattern variable is selected for each reassignment, then add coverage for the example and confirm the transformed program still prints 30 without changing its meaning.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.