@Override public final void visitSource(final String file, final String debug) { if (file != null) { sourceFile = newUTF8(file); } if (debug != null) { sourceDebug = new ByteVector().encodeUTF8(debug, 0, Integer.MAX_VALUE); } }
@Override public AnnotationVisitor visitAnnotation(final String name, final String desc) { ++size; if (named) { bv.putShort(cw.newUTF8(name)); } // write tag and type, and reserve space for values count bv.put12('@', cw.newUTF8(desc)).putShort(0); return new AnnotationWriter(cw, true, bv, bv, bv.length - 2); }
@Override public void visitParameter(String name, int access) { if (methodParameters == null) { methodParameters = new ByteVector(); } ++methodParametersCount; methodParameters.putShort((name == null) ? 0 : cw.newUTF8(name)) .putShort(access); }
@Override public AnnotationVisitor visitArray(final String name) { ++size; if (named) { bv.putShort(cw.newUTF8(name)); } // write tag, and reserve space for array size bv.put12('[', 0); return new AnnotationWriter(cw, false, bv, bv, bv.length - 2); }
/** * Adds a name and type to the constant pool of the class being build. Does * nothing if the constant pool already contains a similar item. * * @param name * a name. * @param desc * a type descriptor. * @return a new or already existing name and type item. */ Item newNameTypeItem(final String name, final String desc) { key2.set(NAME_TYPE, name, desc, null); Item result = get(key2); if (result == null) { put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); result = new Item(index++, key2); put(result); } return result; }
@Override public final void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { this.version = version; this.access = access; this.name = newClass(name); thisName = name; if (ClassReader.SIGNATURES && signature != null) { this.signature = newUTF8(signature); } this.superName = superName == null ? 0 : newClass(superName); if (interfaces != null && interfaces.length > 0) { interfaceCount = interfaces.length; this.interfaces = new int[interfaceCount]; for (int i = 0; i < interfaceCount; ++i) { this.interfaces[i] = newClass(interfaces[i]); } } }
localVarType.putShort(start.position) .putShort(end.position - start.position) .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature)) .putShort(index); localVar.putShort(start.position) .putShort(end.position - start.position) .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc)) .putShort(index); if (compute != NOTHING) {
@Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); if (visible) { aw.next = anns; anns = aw; } else { aw.next = ianns; ianns = aw; } return aw; }
@Override public final AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write type, and reserve space for values count bv.putShort(newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); if (visible) { aw.next = anns; anns = aw; } else { aw.next = ianns; ianns = aw; } return aw; }
@Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); if (visible) { aw.next = anns; anns = aw; } else { aw.next = ianns; ianns = aw; } return aw; }
/** * Adds a class reference to the constant pool of the class being build. * Does nothing if the constant pool already contains a similar item. * <i>This method is intended for {@link Attribute} sub classes, and is * normally not needed by class generators or adapters.</i> * * @param value * the internal name of the class. * @return a new or already existing class reference item. */ Item newClassItem(final String value) { key2.set(CLASS, value, null, null); Item result = get(key2); if (result == null) { pool.put12(CLASS, newUTF8(value)); result = new Item(index++, key2); put(result); } return result; }
/** * Adds a method type reference to the constant pool of the class being * build. Does nothing if the constant pool already contains a similar item. * <i>This method is intended for {@link Attribute} sub classes, and is * normally not needed by class generators or adapters.</i> * * @param methodDesc * method descriptor of the method type. * @return a new or already existing method type reference item. */ Item newMethodTypeItem(final String methodDesc) { key2.set(MTYPE, methodDesc, null, null); Item result = get(key2); if (result == null) { pool.put12(MTYPE, newUTF8(methodDesc)); result = new Item(index++, key2); put(result); } return result; }
@Override public final AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, bv.length - 2); if (visible) { aw.next = tanns; tanns = aw; } else { aw.next = itanns; itanns = aw; } return aw; }
@Override public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8); AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = ctanns; ctanns = aw; } else { aw.next = ictanns; ictanns = aw; } return aw; }
/** * Adds a string to the constant pool of the class being build. Does nothing * if the constant pool already contains a similar item. * * @param value * the String value. * @return a new or already existing string item. */ private Item newString(final String value) { key2.set(STR, value, null, null); Item result = get(key2); if (result == null) { pool.put12(STR, newUTF8(value)); result = new Item(index++, key2); put(result); } return result; }
@Override public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = tanns; tanns = aw; } else { aw.next = itanns; itanns = aw; } return aw; }
@Override public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = tanns; tanns = aw; } else { aw.next = itanns; itanns = aw; } return aw; }
@Override public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = ctanns; ctanns = aw; } else { aw.next = ictanns; ictanns = aw; } return aw; }
@Override public final void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { if (innerClasses == null) { innerClasses = new ByteVector(); } // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the // constant_pool table which represents a class or interface C that is // not a package member must have exactly one corresponding entry in the // classes array". To avoid duplicates we keep track in the intVal field // of the Item of each CONSTANT_Class_info entry C whether an inner // class entry has already been added for C (this field is unused for // class entries, and changing its value does not change the hashcode // and equality tests). If so we store the index of this inner class // entry (plus one) in intVal. This hack allows duplicate detection in // O(1) time. Item nameItem = newClassItem(name); if (nameItem.intVal == 0) { ++innerClassesCount; innerClasses.putShort(nameItem.index); innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); innerClasses.putShort(access); nameItem.intVal = innerClassesCount; } else { // Compare the inner classes entry nameItem.intVal - 1 with the // arguments of this method and throw an exception if there is a // difference? } }