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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions