Storyyeller / Krakatau

Java decompiler, assembler, and disassembler
GNU General Public License v3.0
1.95k stars 220 forks source link

Final field can't be assigned using qualified name in static initialization block #14

Closed ysangkok closed 11 years ago

ysangkok commented 11 years ago

Original code:

class Test {
    final static Object i = new Object();
}

Decompiled (invalid):

class Test {
    final static Object i;

    Test()
    {
        super();
    }

    static
    {
        Object a = new Object();
        Test.i = a;
    }
}

"Test.i" should be just "i".

See Why isn't a qualified static final variable allowed in a static initialization block? (has JLS link)

Storyyeller commented 11 years ago

Unfortunately, I'm not sure this one will be easily fixable. I think this is one of those cases where Java's restrictions makes things impossible to decompile generically.

ysangkok commented 11 years ago

Here's a hack to patch files (I have hundreds of these assignments):

import fileinput
import re

def main(cont):
    res = re.search("package ([^;]*);", cont)
    if not res:
        raise Exception("no package")

    pack = res.group(1)
    new = re.sub(pack + "\.[A-Z][a-zA-Z]*\.([A-Z_]+) = ", lambda matchobj: matchobj.group(1) + " = ", cont)
    return new

if __name__ == "__main__":
    cont = "".join(list(fileinput.input()))
    res = main(cont)
    print(res)
Storyyeller commented 11 years ago

I just changed it to not print the class name for static fields in the current class. I liked the explicit version since it makes it easier to tell apart fields and variables, but it looks like I have no choice here.

ysangkok commented 11 years ago

Thanks!