diff options
author | chibash <chiba@javassist.org> | 2017-06-01 22:46:39 +0900 |
---|---|---|
committer | chibash <chiba@javassist.org> | 2017-06-01 22:46:39 +0900 |
commit | dfd0733e1f73853453ff76086481ebec2e88a624 (patch) | |
tree | 267e33ac3f8c053f5a83d9fb934ca75c938c8a8a /src/main/javassist | |
parent | ab117a9fe31902167b9a74fee1982068e4c4d095 (diff) | |
download | javassist-dfd0733e1f73853453ff76086481ebec2e88a624.tar.gz javassist-dfd0733e1f73853453ff76086481ebec2e88a624.zip |
modifies CtClass#setModifiers() to correctly support inner classes.
Diffstat (limited to 'src/main/javassist')
-rw-r--r-- | src/main/javassist/ClassPool.java | 2 | ||||
-rw-r--r-- | src/main/javassist/CtClassType.java | 45 | ||||
-rw-r--r-- | src/main/javassist/CtNewNestedClass.java | 67 | ||||
-rw-r--r-- | src/main/javassist/bytecode/InnerClassesAttribute.java | 18 |
4 files changed, 56 insertions, 76 deletions
diff --git a/src/main/javassist/ClassPool.java b/src/main/javassist/ClassPool.java index 4be35b5f..89a0067e 100644 --- a/src/main/javassist/ClassPool.java +++ b/src/main/javassist/ClassPool.java @@ -864,7 +864,7 @@ public class ClassPool { */ synchronized CtClass makeNestedClass(String classname) { checkNotFrozen(classname); - CtClass clazz = new CtNewNestedClass(classname, this, false, null); + CtClass clazz = new CtNewClass(classname, this, false, null); cacheCtClass(classname, clazz, true); return clazz; } 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 diff --git a/src/main/javassist/CtNewNestedClass.java b/src/main/javassist/CtNewNestedClass.java deleted file mode 100644 index 8177fde3..00000000 --- a/src/main/javassist/CtNewNestedClass.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package javassist; - -import javassist.bytecode.ClassFile; -import javassist.bytecode.AccessFlag; -import javassist.bytecode.InnerClassesAttribute; - -/** - * A newly created public nested class. - */ -class CtNewNestedClass extends CtNewClass { - CtNewNestedClass(String realName, ClassPool cp, boolean isInterface, - CtClass superclass) { - super(realName, cp, isInterface, superclass); - } - - /** - * This method does not change the STATIC bit. The original value is kept. - */ - public void setModifiers(int mod) { - mod = mod & ~Modifier.STATIC; - super.setModifiers(mod); - updateInnerEntry(mod, getName(), this, true); - } - - private static void updateInnerEntry(int mod, String name, CtClass clazz, boolean outer) { - ClassFile cf = clazz.getClassFile2(); - InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute( - InnerClassesAttribute.tag); - if (ica == null) - return; - - int n = ica.tableLength(); - for (int i = 0; i < n; i++) - if (name.equals(ica.innerClass(i))) { - int acc = ica.accessFlags(i) & AccessFlag.STATIC; - ica.setAccessFlags(i, mod | acc); - 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); - } - - break; - } - } -} diff --git a/src/main/javassist/bytecode/InnerClassesAttribute.java b/src/main/javassist/bytecode/InnerClassesAttribute.java index cf021791..b5b845d7 100644 --- a/src/main/javassist/bytecode/InnerClassesAttribute.java +++ b/src/main/javassist/bytecode/InnerClassesAttribute.java @@ -64,8 +64,10 @@ public class InnerClassesAttribute extends AttributeInfo { /** * Returns the class name indicated * by <code>classes[nth].inner_class_info_index</code>. + * The class name is fully-qualified and separated by dot. * * @return null or the class name. + * @see ConstPool#getClassInfo(int) */ public String innerClass(int nth) { int i = innerClassIndex(nth); @@ -157,6 +159,22 @@ public class InnerClassesAttribute extends AttributeInfo { } /** + * Finds the entry for the given inner class. + * + * @param name the fully-qualified class name separated by dot and $. + * @return the index or -1 if not found. + * @since 3.22 + */ + public int find(String name) { + int n = tableLength(); + for (int i = 0; i < n; i++) + if (name.equals(innerClass(i))) + return i; + + return -1; + } + + /** * Appends a new entry. * * @param inner <code>inner_class_info_index</code> |