Skip to content

Improperly rewrites inside switch case statements #606

@j-baker

Description

@j-baker

Shadow Version

6.1.0

Gradle Version

6.8.0

Expected Behavior

If I am relocating "com.example.Foo" to "relocated.com.example.Foo" then:

switch (someString) {
    case "com.example.Foo": return true;
    default: return false;
}

should be rewritten to something effectively equivalent to either:

switch (someString) {
    case "relocated.com.example.Foo": return true;
    default: return false;
}

or leave the code block unchanged.

Actual Behavior

In real life, Java compiles such a switch-case to something equivalent to

byte branch = -1;
switch (someString.hashCode()) {
    case 718948661:
        if (someString.equals("com.example.Foo")) {
            branch = 0;
        }
        break;
}
switch (branch) {
    case 0: return true;
    default: return false;
}

and what the shadower will do is rewrite it to something roughly equivalent to

byte branch = -1;
switch (someString.hashCode()) {
    case 718948661:
        if (someString.equals("relocated.com.example.Foo")) {
            branch = 0;
        }
        break;
}
switch (branch) {
    case 0: return true;
    default: return false;
}

thus making the code unreachable because it hasn't rewritten the hashcode.

I believe that in such a case, the shadower should not attempt a rewrite of the string constant.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions