📄 ctclasstype.java
字号:
throw new CannotCompileException("cannot add"); getConstructorsCache(); constructorsCache = (CtConstructor)CtMember.append(constructorsCache, c); getClassFile2().addMethod(c.getMethodInfo2()); } public void removeConstructor(CtConstructor m) throws NotFoundException { checkModify(); MethodInfo mi = m.getMethodInfo2(); ClassFile cf = getClassFile2(); if (cf.getMethods().remove(mi)) { constructorsCache = CtMember.remove(constructorsCache, m); memberRemoved = true; } else throw new NotFoundException(m.toString()); } public void addMethod(CtMethod m) throws CannotCompileException { checkModify(); if (m.getDeclaringClass() != this) throw new CannotCompileException("cannot add"); getMethodsCache(); methodsCache = CtMember.append(methodsCache, m); getClassFile2().addMethod(m.getMethodInfo2()); if ((m.getModifiers() & Modifier.ABSTRACT) != 0) setModifiers(getModifiers() | Modifier.ABSTRACT); } public void removeMethod(CtMethod m) throws NotFoundException { checkModify(); MethodInfo mi = m.getMethodInfo2(); ClassFile cf = getClassFile2(); if (cf.getMethods().remove(mi)) { methodsCache = CtMember.remove(methodsCache, m); memberRemoved = true; } else throw new NotFoundException(m.toString()); } public byte[] getAttribute(String name) { AttributeInfo ai = getClassFile2().getAttribute(name); if (ai == null) return null; else return ai.get(); } public void setAttribute(String name, byte[] data) { checkModify(); ClassFile cf = getClassFile2(); cf.addAttribute(new AttributeInfo(cf.getConstPool(), name, data)); } public void instrument(CodeConverter converter) throws CannotCompileException { checkModify(); ClassFile cf = getClassFile2(); ConstPool cp = cf.getConstPool(); List list = cf.getMethods(); int n = list.size(); for (int i = 0; i < n; ++i) { MethodInfo minfo = (MethodInfo)list.get(i); converter.doit(this, minfo, cp); } } public void instrument(ExprEditor editor) throws CannotCompileException { checkModify(); ClassFile cf = getClassFile2(); List list = cf.getMethods(); int n = list.size(); for (int i = 0; i < n; ++i) { MethodInfo minfo = (MethodInfo)list.get(i); editor.doit(this, minfo); } } /** * @see javassist.CtClass#prune() * @see javassist.CtClass#stopPruning(boolean) */ public void prune() { if (wasPruned) return; wasPruned = wasFrozen = true; getClassFile2().prune(); } public void toBytecode(DataOutputStream out) throws CannotCompileException, IOException { try { if (isModified()) { checkPruned("toBytecode"); ClassFile cf = getClassFile2(); if (memberRemoved) { cf.compact(); memberRemoved = false; } modifyClassConstructor(cf); modifyConstructors(cf); cf.write(out); out.flush(); fieldInitializers = null; if (doPruning) { // to save memory cf.prune(); wasPruned = true; } } else { classPool.writeClassfile(getName(), out); // to save memory eraseCache(); classfile = null; } wasFrozen = true; } catch (NotFoundException e) { throw new CannotCompileException(e); } catch (IOException e) { throw new CannotCompileException(e); } } /* See also checkModified() */ private void checkPruned(String method) { if (wasPruned) throw new RuntimeException(method + "(): " + getName() + " was pruned."); } public boolean stopPruning(boolean stop) { boolean prev = !doPruning; doPruning = !stop; return prev; } private void modifyClassConstructor(ClassFile cf) throws CannotCompileException, NotFoundException { if (fieldInitializers == null) return; Bytecode code = new Bytecode(cf.getConstPool(), 0, 0); Javac jv = new Javac(code, this); int stacksize = 0; boolean doInit = false; for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) { CtField f = fi.field; if (Modifier.isStatic(f.getModifiers())) { doInit = true; int s = fi.init.compileIfStatic(f.getType(), f.getName(), code, jv); if (stacksize < s) stacksize = s; } } if (doInit) // need an initializer for static fileds. modifyClassConstructor(cf, code, stacksize, 0); } private void modifyClassConstructor(ClassFile cf, Bytecode code, int stacksize, int localsize) throws CannotCompileException { MethodInfo m = cf.getStaticInitializer(); if (m == null) { code.add(Bytecode.RETURN); code.setMaxStack(stacksize); code.setMaxLocals(localsize); m = new MethodInfo(cf.getConstPool(), "<clinit>", "()V"); m.setAccessFlags(AccessFlag.STATIC); m.setCodeAttribute(code.toCodeAttribute()); cf.addMethod(m); } else { CodeAttribute codeAttr = m.getCodeAttribute(); if (codeAttr == null) throw new CannotCompileException("empty <clinit>"); try { CodeIterator it = codeAttr.iterator(); int pos = it.insertEx(code.get()); it.insert(code.getExceptionTable(), pos); int maxstack = codeAttr.getMaxStack(); if (maxstack < stacksize) codeAttr.setMaxStack(stacksize); int maxlocals = codeAttr.getMaxLocals(); if (maxlocals < localsize) codeAttr.setMaxLocals(localsize); } catch (BadBytecode e) { throw new CannotCompileException(e); } } } private void modifyConstructors(ClassFile cf) throws CannotCompileException, NotFoundException { if (fieldInitializers == null) return; ConstPool cp = cf.getConstPool(); List list = cf.getMethods(); int n = list.size(); for (int i = 0; i < n; ++i) { MethodInfo minfo = (MethodInfo)list.get(i); if (minfo.isConstructor()) { CodeAttribute codeAttr = minfo.getCodeAttribute(); if (codeAttr != null) try { Bytecode init = new Bytecode(cp, 0, codeAttr.getMaxLocals()); CtClass[] params = Descriptor.getParameterTypes( minfo.getDescriptor(), classPool); int stacksize = makeFieldInitializer(init, params); insertAuxInitializer(codeAttr, init, stacksize); } catch (BadBytecode e) { throw new CannotCompileException(e); } } } } private static void insertAuxInitializer(CodeAttribute codeAttr, Bytecode initializer, int stacksize) throws BadBytecode { CodeIterator it = codeAttr.iterator(); int index = it.skipSuperConstructor(); if (index < 0) { index = it.skipThisConstructor(); if (index >= 0) return; // this() is called. // Neither this() or super() is called. } int pos = it.insertEx(initializer.get()); it.insert(initializer.getExceptionTable(), pos); int maxstack = codeAttr.getMaxStack(); if (maxstack < stacksize) codeAttr.setMaxStack(stacksize); } private int makeFieldInitializer(Bytecode code, CtClass[] parameters) throws CannotCompileException, NotFoundException { int stacksize = 0; Javac jv = new Javac(code, this); try { jv.recordParams(parameters, false); } catch (CompileError e) { throw new CannotCompileException(e); } for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) { CtField f = fi.field; if (!Modifier.isStatic(f.getModifiers())) { int s = fi.init.compile(f.getType(), f.getName(), code, parameters, jv); if (stacksize < s) stacksize = s; } } return stacksize; } // Methods used by CtNewWrappedMethod Hashtable getHiddenMethods() { if (hiddenMethods == null) hiddenMethods = new Hashtable(); return hiddenMethods; } int getUniqueNumber() { return uniqueNumberSeed++; } public String makeUniqueName(String prefix) { HashMap table = new HashMap(); makeMemberList(table); Set keys = table.keySet(); String[] methods = new String[keys.size()]; keys.toArray(methods); if (notFindInArray(prefix, methods)) return prefix; int i = 100; String name; do { if (i > 999) throw new RuntimeException("too many unique name"); name = prefix + i++; } while (!notFindInArray(name, methods)); return name; } private static boolean notFindInArray(String prefix, String[] values) { int len = values.length; for (int i = 0; i < len; i++) if (values[i].startsWith(prefix)) return false; return true; } private void makeMemberList(HashMap table) { int mod = getModifiers(); if (Modifier.isAbstract(mod) || Modifier.isInterface(mod)) try { CtClass[] ifs = getInterfaces(); int size = ifs.length; for (int i = 0; i < size; i++) { CtClass ic =ifs[i]; if (ic != null && ic instanceof CtClassType) ((CtClassType)ic).makeMemberList(table); } } catch (NotFoundException e) {} try { CtClass s = getSuperclass(); if (s != null && s instanceof CtClassType) ((CtClassType)s).makeMemberList(table); } catch (NotFoundException e) {} List list = getClassFile2().getMethods(); int n = list.size(); for (int i = 0; i < n; i++) { MethodInfo minfo = (MethodInfo)list.get(i); table.put(minfo.getName(), this); } list = getClassFile2().getFields(); n = list.size(); for (int i = 0; i < n; i++) { FieldInfo finfo = (FieldInfo)list.get(i); table.put(finfo.getName(), this); } }}class FieldInitLink { FieldInitLink next; CtField field; CtField.Initializer init; FieldInitLink(CtField f, CtField.Initializer i) { next = null; field = f; init = i; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -