From dfd0733e1f73853453ff76086481ebec2e88a624 Mon Sep 17 00:00:00 2001 From: chibash Date: Thu, 1 Jun 2017 22:46:39 +0900 Subject: modifies CtClass#setModifiers() to correctly support inner classes. --- src/main/javassist/CtClassType.java | 45 ++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'src/main/javassist/CtClassType.java') diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index 29aace81..b0a8819d 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -453,17 +453,46 @@ class CtClassType extends CtClass { } public void setModifiers(int mod) { + checkModify(); + updateInnerEntry(mod, getName(), this, true); ClassFile cf = getClassFile2(); - if (Modifier.isStatic(mod)) { - int flags = cf.getInnerAccessFlags(); - if (flags != -1 && (flags & AccessFlag.STATIC) != 0) - mod = mod & ~Modifier.STATIC; - else - throw new RuntimeException("cannot change " + getName() + " into a static class"); + cf.setAccessFlags(AccessFlag.of(mod & ~Modifier.STATIC)); + } + + private static void updateInnerEntry(int newMod, String name, CtClass clazz, boolean outer) { + ClassFile cf = clazz.getClassFile2(); + InnerClassesAttribute ica + = (InnerClassesAttribute)cf.getAttribute(InnerClassesAttribute.tag); + if (ica != null) { + // If the class is a static inner class, its modifier + // does not contain the static bit. Its inner class attribute + // contains the static bit. + int mod = newMod & ~Modifier.STATIC; + int i = ica.find(name); + if (i >= 0) { + int isStatic = ica.accessFlags(i) & AccessFlag.STATIC; + if (isStatic != 0 || !Modifier.isStatic(newMod)) { + clazz.checkModify(); + ica.setAccessFlags(i, AccessFlag.of(mod) | isStatic); + String outName = ica.outerClass(i); + if (outName != null && outer) + try { + CtClass parent = clazz.getClassPool().get(outName); + updateInnerEntry(mod, name, parent, false); + } + catch (NotFoundException e) { + throw new RuntimeException("cannot find the declaring class: " + + outName); + } + + return; + } + } } - checkModify(); - cf.setAccessFlags(AccessFlag.of(mod)); + if (Modifier.isStatic(newMod)) + throw new RuntimeException("cannot change " + Descriptor.toJavaName(name) + + " into a static class"); } //@Override -- cgit v1.2.3