From 20d78832b064003ed518485d3770213702d27663 Mon Sep 17 00:00:00 2001 From: Dan Mulloy Date: Wed, 14 Jun 2017 15:41:00 -0400 Subject: [PATCH] Update dependency versions to hopefully work with Java 9 --- .../protocol/reflect/ClassAnalyser.java | 40 +- .../reflect/compiler/BoxingHelper.java | 162 ++++---- .../reflect/compiler/EmptyClassVisitor.java | 57 --- .../reflect/compiler/EmptyMethodVisitor.java | 132 ------- .../reflect/compiler/MethodDescriptor.java | 32 +- .../reflect/compiler/StructureCompiler.java | 350 +++++++++--------- .../wrappers/nbt/TileEntityAccessor.java | 37 +- modules/ProtocolLib/pom.xml | 14 +- .../wrappers/WrappedWatchableObjectTest.java | 25 -- pom.xml | 4 +- 10 files changed, 317 insertions(+), 536 deletions(-) delete mode 100644 modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyClassVisitor.java delete mode 100644 modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyMethodVisitor.java delete mode 100644 modules/ProtocolLib/src/test/java/com/comphenix/protocol/wrappers/WrappedWatchableObjectTest.java diff --git a/modules/API/src/main/java/com/comphenix/protocol/reflect/ClassAnalyser.java b/modules/API/src/main/java/com/comphenix/protocol/reflect/ClassAnalyser.java index faa7adf7..ab95602e 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/reflect/ClassAnalyser.java +++ b/modules/API/src/main/java/com/comphenix/protocol/reflect/ClassAnalyser.java @@ -4,16 +4,11 @@ import java.io.IOException; import java.lang.reflect.Method; import java.util.List; -import net.sf.cglib.asm.ClassReader; -import net.sf.cglib.asm.MethodVisitor; -import net.sf.cglib.asm.Opcodes; -import net.sf.cglib.asm.Type; - import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod.AsmOpcodes; -import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor; -import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor; import com.google.common.collect.Lists; +import net.sf.cglib.asm.*; + public class ClassAnalyser { /** * Represents a method in ASM. @@ -31,11 +26,11 @@ public class ClassAnalyser { public static AsmOpcodes fromIntOpcode(int opcode) { switch (opcode) { - case Opcodes.INVOKEVIRTUAL: return AsmOpcodes.INVOKE_VIRTUAL; - case Opcodes.INVOKESPECIAL: return AsmOpcodes.INVOKE_SPECIAL; - case Opcodes.INVOKESTATIC: return AsmOpcodes.INVOKE_STATIC; - case Opcodes.INVOKEINTERFACE: return AsmOpcodes.INVOKE_INTERFACE; - case Opcodes.INVOKEDYNAMIC: return AsmOpcodes.INVOKE_DYNAMIC; + case $Opcodes.INVOKEVIRTUAL: return AsmOpcodes.INVOKE_VIRTUAL; + case $Opcodes.INVOKESPECIAL: return AsmOpcodes.INVOKE_SPECIAL; + case $Opcodes.INVOKESTATIC: return AsmOpcodes.INVOKE_STATIC; + case $Opcodes.INVOKEINTERFACE: return AsmOpcodes.INVOKE_INTERFACE; + case $Opcodes.INVOKEDYNAMIC: return AsmOpcodes.INVOKE_DYNAMIC; default: throw new IllegalArgumentException("Unknown opcode: " + opcode); } } @@ -109,30 +104,29 @@ public class ClassAnalyser { * @return The method calls. * @throws IOException Cannot access the parent class. */ - public List getMethodCalls(Class clazz, Method method) throws IOException { - final ClassReader reader = new ClassReader(clazz.getCanonicalName()); + private List getMethodCalls(Class clazz, Method method) throws IOException { + final $ClassReader reader = new $ClassReader(clazz.getCanonicalName()); final List output = Lists.newArrayList(); // The method we are looking for final String methodName = method.getName(); - final String methodDescription = Type.getMethodDescriptor(method); - - reader.accept(new EmptyClassVisitor() { + final String methodDescription = $Type.getMethodDescriptor(method); + + reader.accept(new $ClassVisitor($Opcodes.ASM5) { @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - // Check method + public $MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (methodName.equals(name) && methodDescription.equals(desc)) { - return new EmptyMethodVisitor() { + return new $MethodVisitor($Opcodes.ASM5) { @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean flag) { output.add(new AsmMethod(AsmOpcodes.fromIntOpcode(opcode), owner, methodName, desc)); } }; } + return null; } - - }, ClassReader.EXPAND_FRAMES); + }, $ClassReader.EXPAND_FRAMES); return output; } } diff --git a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/BoxingHelper.java b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/BoxingHelper.java index ad34e502..7d5938f9 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/BoxingHelper.java +++ b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/BoxingHelper.java @@ -17,25 +17,25 @@ package com.comphenix.protocol.reflect.compiler; -import net.sf.cglib.asm.MethodVisitor; -import net.sf.cglib.asm.Opcodes; -import net.sf.cglib.asm.Type; +import net.sf.cglib.asm.$MethodVisitor; +import net.sf.cglib.asm.$Opcodes; +import net.sf.cglib.asm.$Type; /** * Used by the compiler to automatically box and unbox values. */ class BoxingHelper { - private final static Type BYTE_TYPE = Type.getObjectType("java/lang/Byte"); - private final static Type BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean"); - private final static Type SHORT_TYPE = Type.getObjectType("java/lang/Short"); - private final static Type CHARACTER_TYPE = Type.getObjectType("java/lang/Character"); - private final static Type INTEGER_TYPE = Type.getObjectType("java/lang/Integer"); - private final static Type FLOAT_TYPE = Type.getObjectType("java/lang/Float"); - private final static Type LONG_TYPE = Type.getObjectType("java/lang/Long"); - private final static Type DOUBLE_TYPE = Type.getObjectType("java/lang/Double"); - private final static Type NUMBER_TYPE = Type.getObjectType("java/lang/Number"); - private final static Type OBJECT_TYPE = Type.getObjectType("java/lang/Object"); + private final static $Type BYTE_$Type = $Type.getObjectType("java/lang/Byte"); + private final static $Type BOOLEAN_$Type = $Type.getObjectType("java/lang/Boolean"); + private final static $Type SHORT_$Type = $Type.getObjectType("java/lang/Short"); + private final static $Type CHARACTER_$Type = $Type.getObjectType("java/lang/Character"); + private final static $Type INTEGER_$Type = $Type.getObjectType("java/lang/Integer"); + private final static $Type FLOAT_$Type = $Type.getObjectType("java/lang/Float"); + private final static $Type LONG_$Type = $Type.getObjectType("java/lang/Long"); + private final static $Type DOUBLE_$Type = $Type.getObjectType("java/lang/Double"); + private final static $Type NUMBER_$Type = $Type.getObjectType("java/lang/Number"); + private final static $Type OBJECT_$Type = $Type.getObjectType("java/lang/Object"); private final static MethodDescriptor BOOLEAN_VALUE = MethodDescriptor.getMethod("boolean booleanValue()"); private final static MethodDescriptor CHAR_VALUE = MethodDescriptor.getMethod("char charValue()"); @@ -44,9 +44,9 @@ class BoxingHelper { private final static MethodDescriptor LONG_VALUE = MethodDescriptor.getMethod("long longValue()"); private final static MethodDescriptor DOUBLE_VALUE = MethodDescriptor.getMethod("double doubleValue()"); - private MethodVisitor mv; + private $MethodVisitor mv; - public BoxingHelper(MethodVisitor mv) { + public BoxingHelper($MethodVisitor mv) { this.mv = mv; } @@ -54,42 +54,42 @@ class BoxingHelper { * Generates the instructions to box the top stack value. This value is * replaced by its boxed equivalent on top of the stack. * - * @param type the type of the top stack value. + * @param type the $Type of the top stack value. */ - public void box(final Type type){ - if(type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { + public void box(final $Type type){ + if(type.getSort() == $Type.OBJECT || type.getSort() == $Type.ARRAY) { return; } - if(type == Type.VOID_TYPE) { + if(type == $Type.VOID_TYPE) { push((String) null); } else { - Type boxed = type; + $Type boxed = type; switch(type.getSort()) { - case Type.BYTE: - boxed = BYTE_TYPE; + case $Type.BYTE: + boxed = BYTE_$Type; break; - case Type.BOOLEAN: - boxed = BOOLEAN_TYPE; + case $Type.BOOLEAN: + boxed = BOOLEAN_$Type; break; - case Type.SHORT: - boxed = SHORT_TYPE; + case $Type.SHORT: + boxed = SHORT_$Type; break; - case Type.CHAR: - boxed = CHARACTER_TYPE; + case $Type.CHAR: + boxed = CHARACTER_$Type; break; - case Type.INT: - boxed = INTEGER_TYPE; + case $Type.INT: + boxed = INTEGER_$Type; break; - case Type.FLOAT: - boxed = FLOAT_TYPE; + case $Type.FLOAT: + boxed = FLOAT_$Type; break; - case Type.LONG: - boxed = LONG_TYPE; + case $Type.LONG: + boxed = LONG_$Type; break; - case Type.DOUBLE: - boxed = DOUBLE_TYPE; + case $Type.DOUBLE: + boxed = DOUBLE_$Type; break; } @@ -105,46 +105,46 @@ class BoxingHelper { swap(); } - invokeConstructor(boxed, new MethodDescriptor("", Type.VOID_TYPE, new Type[] {type})); + invokeConstructor(boxed, new MethodDescriptor("", $Type.VOID_TYPE, new $Type[] {type})); } } /** * Generates the instruction to invoke a constructor. * - * @param type the class in which the constructor is defined. + * @param $Type the class in which the constructor is defined. * @param method the constructor to be invoked. */ - public void invokeConstructor(final Type type, final MethodDescriptor method){ - invokeInsn(Opcodes.INVOKESPECIAL, type, method); + public void invokeConstructor(final $Type $Type, final MethodDescriptor method){ + invokeInsn($Opcodes.INVOKESPECIAL, $Type, method); } /** * Generates a DUP_X1 instruction. */ public void dupX1(){ - mv.visitInsn(Opcodes.DUP_X1); + mv.visitInsn($Opcodes.DUP_X1); } /** * Generates a DUP_X2 instruction. */ public void dupX2(){ - mv.visitInsn(Opcodes.DUP_X2); + mv.visitInsn($Opcodes.DUP_X2); } /** * Generates a POP instruction. */ public void pop(){ - mv.visitInsn(Opcodes.POP); + mv.visitInsn($Opcodes.POP); } /** * Generates a SWAP instruction. */ public void swap(){ - mv.visitInsn(Opcodes.SWAP); + mv.visitInsn($Opcodes.SWAP); } /** @@ -163,11 +163,11 @@ class BoxingHelper { */ public void push(final int value) { if (value >= -1 && value <= 5) { - mv.visitInsn(Opcodes.ICONST_0 + value); + mv.visitInsn($Opcodes.ICONST_0 + value); } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { - mv.visitIntInsn(Opcodes.BIPUSH, value); + mv.visitIntInsn($Opcodes.BIPUSH, value); } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { - mv.visitIntInsn(Opcodes.SIPUSH, value); + mv.visitIntInsn($Opcodes.SIPUSH, value); } else { mv.visitLdcInsn(new Integer(value)); } @@ -176,10 +176,10 @@ class BoxingHelper { /** * Generates the instruction to create a new object. * - * @param type the class of the object to be created. + * @param $Type the class of the object to be created. */ - public void newInstance(final Type type){ - typeInsn(Opcodes.NEW, type); + public void newInstance(final $Type $Type){ + $TypeInsn($Opcodes.NEW, $Type); } /** @@ -189,7 +189,7 @@ class BoxingHelper { */ public void push(final String value) { if (value == null) { - mv.visitInsn(Opcodes.ACONST_NULL); + mv.visitInsn($Opcodes.ACONST_NULL); } else { mv.visitLdcInsn(value); } @@ -200,35 +200,35 @@ class BoxingHelper { * replaced by its unboxed equivalent on top of the stack. * * @param type - * the type of the top stack value. + * the $Type of the top stack value. */ - public void unbox(final Type type){ - Type t = NUMBER_TYPE; + public void unbox(final $Type type){ + $Type t = NUMBER_$Type; MethodDescriptor sig = null; switch(type.getSort()) { - case Type.VOID: + case $Type.VOID: return; - case Type.CHAR: - t = CHARACTER_TYPE; + case $Type.CHAR: + t = CHARACTER_$Type; sig = CHAR_VALUE; break; - case Type.BOOLEAN: - t = BOOLEAN_TYPE; + case $Type.BOOLEAN: + t = BOOLEAN_$Type; sig = BOOLEAN_VALUE; break; - case Type.DOUBLE: + case $Type.DOUBLE: sig = DOUBLE_VALUE; break; - case Type.FLOAT: + case $Type.FLOAT: sig = FLOAT_VALUE; break; - case Type.LONG: + case $Type.LONG: sig = LONG_VALUE; break; - case Type.INT: - case Type.SHORT: - case Type.BYTE: + case $Type.INT: + case $Type.SHORT: + case $Type.BYTE: sig = INT_VALUE; } @@ -242,13 +242,13 @@ class BoxingHelper { /** * Generates the instruction to check that the top stack value is of the - * given type. + * given $Type. * - * @param type a class or interface type. + * @param $Type a class or interface $Type. */ - public void checkCast(final Type type){ - if(!type.equals(OBJECT_TYPE)) { - typeInsn(Opcodes.CHECKCAST, type); + public void checkCast(final $Type $Type){ + if(!$Type.equals(OBJECT_$Type)) { + $TypeInsn($Opcodes.CHECKCAST, $Type); } } @@ -258,35 +258,35 @@ class BoxingHelper { * @param owner the class in which the method is defined. * @param method the method to be invoked. */ - public void invokeVirtual(final Type owner, final MethodDescriptor method){ - invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method); + public void invokeVirtual(final $Type owner, final MethodDescriptor method){ + invokeInsn($Opcodes.INVOKEVIRTUAL, owner, method); } /** * Generates an invoke method instruction. * * @param opcode the instruction's opcode. - * @param type the class in which the method is defined. + * @param $Type the class in which the method is defined. * @param method the method to be invoked. */ - private void invokeInsn(final int opcode, final Type type, final MethodDescriptor method){ - String owner = type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName(); + private void invokeInsn(final int opcode, final $Type $Type, final MethodDescriptor method){ + String owner = $Type.getSort() == $Type.ARRAY ? $Type.getDescriptor() : $Type.getInternalName(); mv.visitMethodInsn(opcode, owner, method.getName(), method.getDescriptor()); } /** - * Generates a type dependent instruction. + * Generates a $Type dependent instruction. * * @param opcode the instruction's opcode. - * @param type the instruction's operand. + * @param $Type the instruction's operand. */ - private void typeInsn(final int opcode, final Type type){ + private void $TypeInsn(final int opcode, final $Type $Type){ String desc; - if(type.getSort() == Type.ARRAY) { - desc = type.getDescriptor(); + if($Type.getSort() == $Type.ARRAY) { + desc = $Type.getDescriptor(); } else { - desc = type.getInternalName(); + desc = $Type.getInternalName(); } mv.visitTypeInsn(opcode, desc); diff --git a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyClassVisitor.java b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyClassVisitor.java deleted file mode 100644 index 495eb6c7..00000000 --- a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyClassVisitor.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.comphenix.protocol.reflect.compiler; - -import net.sf.cglib.asm.AnnotationVisitor; -import net.sf.cglib.asm.Attribute; -import net.sf.cglib.asm.ClassVisitor; -import net.sf.cglib.asm.FieldVisitor; -import net.sf.cglib.asm.MethodVisitor; - -public abstract class EmptyClassVisitor implements ClassVisitor { - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - // NOP - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - // NOP - return null; - } - - @Override - public void visitAttribute(Attribute attr) { - // NOP - } - - @Override - public void visitEnd() { - // NOP - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - // NOP - return null; - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - // NOP - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - // NOP - return null; - } - - @Override - public void visitOuterClass(String owner, String name, String desc) { - // NOP - } - - @Override - public void visitSource(String source, String debug) { - // NOP - } -} diff --git a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyMethodVisitor.java b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyMethodVisitor.java deleted file mode 100644 index de648408..00000000 --- a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/EmptyMethodVisitor.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.comphenix.protocol.reflect.compiler; - -import net.sf.cglib.asm.AnnotationVisitor; -import net.sf.cglib.asm.Attribute; -import net.sf.cglib.asm.Label; -import net.sf.cglib.asm.MethodVisitor; - -public class EmptyMethodVisitor implements MethodVisitor { - @Override - public AnnotationVisitor visitAnnotationDefault() { - // NOP - return null; - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - // NOP - return null; - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { - // NOP - return null; - } - - @Override - public void visitAttribute(Attribute attr) { - // NOP - } - - @Override - public void visitCode() { - // NOP - } - - @Override - public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { - // NOP - } - - @Override - public void visitInsn(int opcode) { - // NOP - } - - @Override - public void visitIntInsn(int opcode, int operand) { - // NOP - } - - @Override - public void visitVarInsn(int opcode, int var) { - // NOP - } - - @Override - public void visitTypeInsn(int opcode, String type) { - // NOP - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - // NOP - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - // NOP - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - // NOP - } - - @Override - public void visitLabel(Label label) { - // NOP - } - - @Override - public void visitLdcInsn(Object cst) { - // NOP - } - - @Override - public void visitIincInsn(int var, int increment) { - // NOP - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { - // NOP - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - // NOP - } - - @Override - public void visitMultiANewArrayInsn(String desc, int dims) { - // NOP - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - // NOP - } - - @Override - public void visitLocalVariable(String name, String desc, String signature, Label start, - Label end, int index) { - // NOP - } - - @Override - public void visitLineNumber(int line, Label start) { - // NOP - } - - @Override - public void visitMaxs(int maxStack, int maxLocals) { - // NOP - } - - @Override - public void visitEnd() { - // NOP - } -} diff --git a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/MethodDescriptor.java b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/MethodDescriptor.java index a8767dfe..71a6ffd8 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/MethodDescriptor.java +++ b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/MethodDescriptor.java @@ -20,7 +20,7 @@ package com.comphenix.protocol.reflect.compiler; import java.util.HashMap; import java.util.Map; -import net.sf.cglib.asm.Type; +import net.sf.cglib.asm.$Type; /** * Represents a method. @@ -56,7 +56,7 @@ class MethodDescriptor { } /** - * Creates a new {@link Method}. + * Creates a new {@link MethodDescriptor}. * * @param name the method's name. * @param desc the method's descriptor. @@ -67,7 +67,7 @@ class MethodDescriptor { } /** - * Creates a new {@link Method}. + * Creates a new {@link MethodDescriptor}. * * @param name the method's name. * @param returnType the method's return type. @@ -75,14 +75,14 @@ class MethodDescriptor { */ public MethodDescriptor( final String name, - final Type returnType, - final Type[] argumentTypes) + final $Type returnType, + final $Type[] argumentTypes) { - this(name, Type.getMethodDescriptor(returnType, argumentTypes)); + this(name, $Type.getMethodDescriptor(returnType, argumentTypes)); } /** - * Returns a {@link Method} corresponding to the given Java method + * Returns a {@link MethodDescriptor} corresponding to the given Java method * declaration. * * @param method a Java method declaration, without argument names, of the @@ -91,7 +91,7 @@ class MethodDescriptor { * "java.util.List", ...). Classes of the java.lang package can be * specified by their unqualified name; all other classes names must * be fully qualified. - * @return a {@link Method} corresponding to the given Java method + * @return a {@link MethodDescriptor} corresponding to the given Java method * declaration. * @throws IllegalArgumentException if method could not get * parsed. @@ -103,7 +103,7 @@ class MethodDescriptor { } /** - * Returns a {@link Method} corresponding to the given Java method + * Returns a {@link MethodDescriptor} corresponding to the given Java method * declaration. * * @param method a Java method declaration, without argument names, of the @@ -117,7 +117,7 @@ class MethodDescriptor { * default package, or false if they correspond to java.lang classes. * For instance "Object" means "Object" if this option is true, or * "java.lang.Object" otherwise. - * @return a {@link Method} corresponding to the given Java method + * @return a {@link MethodDescriptor} corresponding to the given Java method * declaration. * @throws IllegalArgumentException if method could not get * parsed. @@ -134,7 +134,7 @@ class MethodDescriptor { } String returnType = method.substring(0, space); String methodName = method.substring(space + 1, start - 1).trim(); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append('('); int p; do { @@ -158,7 +158,7 @@ class MethodDescriptor { return type; } - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); int index = 0; while ((index = type.indexOf("[]", index) + 1) > 0) { sb.append('['); @@ -206,8 +206,8 @@ class MethodDescriptor { * * @return the return type of the method described by this object. */ - public Type getReturnType() { - return Type.getReturnType(desc); + public $Type getReturnType() { + return $Type.getReturnType(desc); } /** @@ -215,8 +215,8 @@ class MethodDescriptor { * * @return the argument types of the method described by this object. */ - public Type[] getArgumentTypes() { - return Type.getArgumentTypes(desc); + public $Type[] getArgumentTypes() { + return $Type.getArgumentTypes(desc); } public String toString() { diff --git a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/StructureCompiler.java b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/StructureCompiler.java index ccaab3c1..5f9af5e6 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/StructureCompiler.java +++ b/modules/API/src/main/java/com/comphenix/protocol/reflect/compiler/StructureCompiler.java @@ -25,12 +25,12 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import net.sf.cglib.asm.ClassWriter; -import net.sf.cglib.asm.FieldVisitor; -import net.sf.cglib.asm.Label; -import net.sf.cglib.asm.MethodVisitor; -import net.sf.cglib.asm.Opcodes; -import net.sf.cglib.asm.Type; +import net.sf.cglib.asm.$ClassWriter; +import net.sf.cglib.asm.$FieldVisitor; +import net.sf.cglib.asm.$Label; +import net.sf.cglib.asm.$MethodVisitor; +import net.sf.cglib.asm.$Opcodes; +import net.sf.cglib.asm.$Type; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.error.Report; @@ -95,22 +95,22 @@ import com.google.common.primitives.Primitives; /** * Represents a StructureModifier compiler. - * + * * @author Kristian */ public final class StructureCompiler { public static final ReportType REPORT_TOO_MANY_GENERATED_CLASSES = new ReportType("Generated too many classes (count: %s)"); - + // Used to store generated classes of different types @SuppressWarnings("rawtypes") static class StructureKey { private Class targetType; private Class fieldType; - + public StructureKey(StructureModifier source) { this(source.getTargetType(), source.getFieldType()); } - + public StructureKey(Class targetType, Class fieldType) { this.targetType = targetType; this.fieldType = fieldType; @@ -120,7 +120,7 @@ public final class StructureCompiler { public int hashCode() { return Objects.hashCode(targetType, fieldType); } - + @Override public boolean equals(Object obj) { if (obj instanceof StructureKey) { @@ -131,16 +131,16 @@ public final class StructureCompiler { return false; } } - + // Used to load classes private volatile static Method defineMethod; - + @SuppressWarnings("rawtypes") private Map compiledCache = new ConcurrentHashMap(); - + // The class loader we'll store our classes private ClassLoader loader; - + // References to other classes private static String PACKAGE_NAME = "com/comphenix/protocol/reflect/compiler"; private static String SUPER_CLASS = "com/comphenix/protocol/reflect/StructureModifier"; @@ -156,7 +156,7 @@ public final class StructureCompiler { StructureCompiler(ClassLoader loader) { this.loader = loader; } - + /** * Lookup the current class loader for any previously generated classes before we attempt to generate something. * @param Type @@ -194,7 +194,7 @@ public final class StructureCompiler { // We need to compile the class return false; } - + /** * Compiles the given structure modifier. *

@@ -211,15 +211,15 @@ public final class StructureCompiler { if (!isAnyPublic(source.getFields())) { return source; } - + StructureKey key = new StructureKey(source); Class compiledClass = compiledCache.get(key); - + if (!compiledCache.containsKey(key)) { compiledClass = generateClass(source); compiledCache.put(key, compiledClass); } - + // Next, create an instance of this class try { return (StructureModifier) compiledClass.getConstructor( @@ -245,7 +245,7 @@ public final class StructureCompiler { throw new IllegalStateException("Cannot happen.", e); } } - + /** * Retrieve a variable identifier that can uniquely represent the given type. * @param type - a type. @@ -254,7 +254,7 @@ public final class StructureCompiler { private String getSafeTypeName(Class type) { return type.getCanonicalName().replace("[]", "Array").replace(".", "_"); } - + /** * Retrieve the compiled name of a given structure modifier. * @param source - the structure modifier. @@ -262,29 +262,29 @@ public final class StructureCompiler { */ private String getCompiledName(StructureModifier source) { Class targetType = source.getTargetType(); - + // Concat class and field type return "CompiledStructure$" + getSafeTypeName(targetType) + "$" + getSafeTypeName(source.getFieldType()); } - + /** * Compile a structure modifier. * @param source - structure modifier. * @return The compiled structure modifier. */ private Class generateClass(StructureModifier source) { - - ClassWriter cw = new ClassWriter(0); + + $ClassWriter cw = new $ClassWriter(0); Class targetType = source.getTargetType(); - + String className = getCompiledName(source); - String targetSignature = Type.getDescriptor(targetType); + String targetSignature = $Type.getDescriptor(targetType); String targetName = targetType.getName().replace('.', '/'); - + // Define class - cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, PACKAGE_NAME + "/" + className, + cw.visit($Opcodes.V1_6, $Opcodes.ACC_PUBLIC + $Opcodes.ACC_SUPER, PACKAGE_NAME + "/" + className, null, COMPILED_CLASS, null); createFields(cw, targetSignature); @@ -292,29 +292,29 @@ public final class StructureCompiler { createReadMethod(cw, className, source.getFields(), targetSignature, targetName); createWriteMethod(cw, className, source.getFields(), targetSignature, targetName); cw.visitEnd(); - + byte[] data = cw.toByteArray(); - + // Call the define method try { if (defineMethod == null) { Method defined = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class }); - + // Awesome. Now, create and return it. defined.setAccessible(true); defineMethod = defined; } - + @SuppressWarnings("rawtypes") Class clazz = (Class) defineMethod.invoke(loader, null, data, 0, data.length); - + // DEBUG CODE: Print the content of the generated class. //org.objectweb.asm.ClassReader cr = new org.objectweb.asm.ClassReader(data); //cr.accept(new ASMifierClassVisitor(new PrintWriter(System.out)), 0); - + return clazz; - + } catch (SecurityException e) { throw new RuntimeException("Cannot use reflection to dynamically load a class.", e); } catch (NoSuchMethodException e) { @@ -327,7 +327,7 @@ public final class StructureCompiler { throw new RuntimeException("Error occured in code generator.", e); } } - + /** * Determine if at least one of the given fields is public. * @param fields - field to test. @@ -340,208 +340,208 @@ public final class StructureCompiler { return true; } } - + return false; } - + private boolean isPublic(Field field) { return Modifier.isPublic(field.getModifiers()); } - + private boolean isNonFinal(Field field) { return !Modifier.isFinal(field.getModifiers()); } - - private void createFields(ClassWriter cw, String targetSignature) { - FieldVisitor typedField = cw.visitField(Opcodes.ACC_PRIVATE, "typedTarget", targetSignature, null, null); + + private void createFields($ClassWriter cw, String targetSignature) { + $FieldVisitor typedField = cw.visitField($Opcodes.ACC_PRIVATE, "typedTarget", targetSignature, null, null); typedField.visitEnd(); } - - private void createWriteMethod(ClassWriter cw, String className, List fields, String targetSignature, String targetName) { - + + private void createWriteMethod($ClassWriter cw, String className, List fields, String targetSignature, String targetName) { + String methodDescriptor = "(ILjava/lang/Object;)L" + SUPER_CLASS + ";"; String methodSignature = "(ILjava/lang/Object;)L" + SUPER_CLASS + ";"; - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PROTECTED, "writeGenerated", methodDescriptor, methodSignature, + $MethodVisitor mv = cw.visitMethod($Opcodes.ACC_PROTECTED, "writeGenerated", methodDescriptor, methodSignature, new String[] { FIELD_EXCEPTION_CLASS }); BoxingHelper boxingHelper = new BoxingHelper(mv); - - String generatedClassName = PACKAGE_NAME + "/" + className; - - mv.visitCode(); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitFieldInsn(Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature); - mv.visitVarInsn(Opcodes.ASTORE, 3); - mv.visitVarInsn(Opcodes.ILOAD, 1); - // The last label is for the default switch - Label[] labels = new Label[fields.size()]; - Label errorLabel = new Label(); - Label returnLabel = new Label(); - - // Generate labels + String generatedClassName = PACKAGE_NAME + "/" + className; + + mv.visitCode(); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitFieldInsn($Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature); + mv.visitVarInsn($Opcodes.ASTORE, 3); + mv.visitVarInsn($Opcodes.ILOAD, 1); + + // The last $Label is for the default switch + $Label[] $Labels = new $Label[fields.size()]; + $Label error$Label = new $Label(); + $Label return$Label = new $Label(); + + // Generate $Labels for (int i = 0; i < fields.size(); i++) { - labels[i] = new Label(); + $Labels[i] = new $Label(); } - - mv.visitTableSwitchInsn(0, labels.length - 1, errorLabel, labels); - + + mv.visitTableSwitchInsn(0, $Labels.length - 1, error$Label, $Labels); + for (int i = 0; i < fields.size(); i++) { - + Field field = fields.get(i); Class outputType = field.getType(); Class inputType = Primitives.wrap(outputType); - String typeDescriptor = Type.getDescriptor(outputType); + String typeDescriptor = $Type.getDescriptor(outputType); String inputPath = inputType.getName().replace('.', '/'); - - mv.visitLabel(labels[i]); - + + mv.visitLabel($Labels[i]); + // Push the compare object if (i == 0) - mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { targetName }, 0, null); + mv.visitFrame($Opcodes.F_APPEND, 1, new Object[] { targetName }, 0, null); else - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - + mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null); + // Only write to public non-final fields if (isPublic(field) && isNonFinal(field)) { - mv.visitVarInsn(Opcodes.ALOAD, 3); - mv.visitVarInsn(Opcodes.ALOAD, 2); - + mv.visitVarInsn($Opcodes.ALOAD, 3); + mv.visitVarInsn($Opcodes.ALOAD, 2); + if (!outputType.isPrimitive()) - mv.visitTypeInsn(Opcodes.CHECKCAST, inputPath); + mv.visitTypeInsn($Opcodes.CHECKCAST, inputPath); else - boxingHelper.unbox(Type.getType(outputType)); - - mv.visitFieldInsn(Opcodes.PUTFIELD, targetName, field.getName(), typeDescriptor); - + boxingHelper.unbox($Type.getType(outputType)); + + mv.visitFieldInsn($Opcodes.PUTFIELD, targetName, field.getName(), typeDescriptor); + } else { // Use reflection. We don't have a choice, unfortunately. - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitVarInsn(Opcodes.ALOAD, 2); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, generatedClassName, "writeReflected", "(ILjava/lang/Object;)V"); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitVarInsn($Opcodes.ILOAD, 1); + mv.visitVarInsn($Opcodes.ALOAD, 2); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, generatedClassName, "writeReflected", "(ILjava/lang/Object;)V"); } - - mv.visitJumpInsn(Opcodes.GOTO, returnLabel); + + mv.visitJumpInsn($Opcodes.GOTO, return$Label); } - - mv.visitLabel(errorLabel); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitTypeInsn(Opcodes.NEW, FIELD_EXCEPTION_CLASS); - mv.visitInsn(Opcodes.DUP); - mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); - mv.visitInsn(Opcodes.DUP); + + mv.visitLabel(error$Label); + mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null); + mv.visitTypeInsn($Opcodes.NEW, FIELD_EXCEPTION_CLASS); + mv.visitInsn($Opcodes.DUP); + mv.visitTypeInsn($Opcodes.NEW, "java/lang/StringBuilder"); + mv.visitInsn($Opcodes.DUP); mv.visitLdcInsn("Invalid index "); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "", "(Ljava/lang/String;)V"); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "", "(Ljava/lang/String;)V"); - mv.visitInsn(Opcodes.ATHROW); - - mv.visitLabel(returnLabel); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitInsn(Opcodes.ARETURN); + mv.visitMethodInsn($Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "", "(Ljava/lang/String;)V"); + mv.visitVarInsn($Opcodes.ILOAD, 1); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); + mv.visitMethodInsn($Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "", "(Ljava/lang/String;)V"); + mv.visitInsn($Opcodes.ATHROW); + + mv.visitLabel(return$Label); + mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitInsn($Opcodes.ARETURN); mv.visitMaxs(5, 4); mv.visitEnd(); } - private void createReadMethod(ClassWriter cw, String className, List fields, String targetSignature, String targetName) { - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PROTECTED, "readGenerated", "(I)Ljava/lang/Object;", null, + private void createReadMethod($ClassWriter cw, String className, List fields, String targetSignature, String targetName) { + $MethodVisitor mv = cw.visitMethod($Opcodes.ACC_PROTECTED, "readGenerated", "(I)Ljava/lang/Object;", null, new String[] { "com/comphenix/protocol/reflect/FieldAccessException" }); BoxingHelper boxingHelper = new BoxingHelper(mv); - - String generatedClassName = PACKAGE_NAME + "/" + className; - - mv.visitCode(); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitFieldInsn(Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature); - mv.visitVarInsn(Opcodes.ASTORE, 2); - mv.visitVarInsn(Opcodes.ILOAD, 1); - // The last label is for the default switch - Label[] labels = new Label[fields.size()]; - Label errorLabel = new Label(); - - // Generate labels + String generatedClassName = PACKAGE_NAME + "/" + className; + + mv.visitCode(); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitFieldInsn($Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature); + mv.visitVarInsn($Opcodes.ASTORE, 2); + mv.visitVarInsn($Opcodes.ILOAD, 1); + + // The last $Label is for the default switch + $Label[] $Labels = new $Label[fields.size()]; + $Label error$Label = new $Label(); + + // Generate $Labels for (int i = 0; i < fields.size(); i++) { - labels[i] = new Label(); + $Labels[i] = new $Label(); } - - mv.visitTableSwitchInsn(0, fields.size() - 1, errorLabel, labels); - + + mv.visitTableSwitchInsn(0, fields.size() - 1, error$Label, $Labels); + for (int i = 0; i < fields.size(); i++) { - + Field field = fields.get(i); Class outputType = field.getType(); - String typeDescriptor = Type.getDescriptor(outputType); - - mv.visitLabel(labels[i]); - + String typeDescriptor = $Type.getDescriptor(outputType); + + mv.visitLabel($Labels[i]); + // Push the compare object if (i == 0) - mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { targetName }, 0, null); + mv.visitFrame($Opcodes.F_APPEND, 1, new Object[] { targetName }, 0, null); else - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - + mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null); + // Note that byte code cannot access non-public fields if (isPublic(field)) { - mv.visitVarInsn(Opcodes.ALOAD, 2); - mv.visitFieldInsn(Opcodes.GETFIELD, targetName, field.getName(), typeDescriptor); - - boxingHelper.box(Type.getType(outputType)); + mv.visitVarInsn($Opcodes.ALOAD, 2); + mv.visitFieldInsn($Opcodes.GETFIELD, targetName, field.getName(), typeDescriptor); + + boxingHelper.box($Type.getType(outputType)); } else { // We have to use reflection for private and protected fields. - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, generatedClassName, "readReflected", "(I)Ljava/lang/Object;"); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitVarInsn($Opcodes.ILOAD, 1); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, generatedClassName, "readReflected", "(I)Ljava/lang/Object;"); } - - mv.visitInsn(Opcodes.ARETURN); + + mv.visitInsn($Opcodes.ARETURN); } - mv.visitLabel(errorLabel); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitTypeInsn(Opcodes.NEW, FIELD_EXCEPTION_CLASS); - mv.visitInsn(Opcodes.DUP); - mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); - mv.visitInsn(Opcodes.DUP); + mv.visitLabel(error$Label); + mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null); + mv.visitTypeInsn($Opcodes.NEW, FIELD_EXCEPTION_CLASS); + mv.visitInsn($Opcodes.DUP); + mv.visitTypeInsn($Opcodes.NEW, "java/lang/StringBuilder"); + mv.visitInsn($Opcodes.DUP); mv.visitLdcInsn("Invalid index "); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "", "(Ljava/lang/String;)V"); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "", "(Ljava/lang/String;)V"); - mv.visitInsn(Opcodes.ATHROW); + mv.visitMethodInsn($Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "", "(Ljava/lang/String;)V"); + mv.visitVarInsn($Opcodes.ILOAD, 1); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); + mv.visitMethodInsn($Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "", "(Ljava/lang/String;)V"); + mv.visitInsn($Opcodes.ATHROW); mv.visitMaxs(5, 3); mv.visitEnd(); } - private void createConstructor(ClassWriter cw, String className, String targetSignature, String targetName) { - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", + private void createConstructor($ClassWriter cw, String className, String targetSignature, String targetName) { + $MethodVisitor mv = cw.visitMethod($Opcodes.ACC_PUBLIC, "", "(L" + SUPER_CLASS + ";L" + PACKAGE_NAME + "/StructureCompiler;)V", "(L" + SUPER_CLASS + ";L" + PACKAGE_NAME + "/StructureCompiler;)V", null); String fullClassName = PACKAGE_NAME + "/" + className; - + mv.visitCode(); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, COMPILED_CLASS, "", "()V"); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitVarInsn(Opcodes.ALOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, fullClassName, "initialize", "(L" + SUPER_CLASS + ";)V"); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitVarInsn(Opcodes.ALOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SUPER_CLASS, "getTarget", "()Ljava/lang/Object;"); - mv.visitFieldInsn(Opcodes.PUTFIELD, fullClassName, "target", "Ljava/lang/Object;"); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitFieldInsn(Opcodes.GETFIELD, fullClassName, "target", "Ljava/lang/Object;"); - mv.visitTypeInsn(Opcodes.CHECKCAST, targetName); - mv.visitFieldInsn(Opcodes.PUTFIELD, fullClassName, "typedTarget", targetSignature); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitVarInsn(Opcodes.ALOAD, 2); - mv.visitFieldInsn(Opcodes.PUTFIELD, fullClassName, "compiler", "L" + PACKAGE_NAME + "/StructureCompiler;"); - mv.visitInsn(Opcodes.RETURN); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitMethodInsn($Opcodes.INVOKESPECIAL, COMPILED_CLASS, "", "()V"); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitVarInsn($Opcodes.ALOAD, 1); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, fullClassName, "initialize", "(L" + SUPER_CLASS + ";)V"); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitVarInsn($Opcodes.ALOAD, 1); + mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, SUPER_CLASS, "getTarget", "()Ljava/lang/Object;"); + mv.visitFieldInsn($Opcodes.PUTFIELD, fullClassName, "target", "Ljava/lang/Object;"); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitFieldInsn($Opcodes.GETFIELD, fullClassName, "target", "Ljava/lang/Object;"); + mv.visitTypeInsn($Opcodes.CHECKCAST, targetName); + mv.visitFieldInsn($Opcodes.PUTFIELD, fullClassName, "typedTarget", targetSignature); + mv.visitVarInsn($Opcodes.ALOAD, 0); + mv.visitVarInsn($Opcodes.ALOAD, 2); + mv.visitFieldInsn($Opcodes.PUTFIELD, fullClassName, "compiler", "L" + PACKAGE_NAME + "/StructureCompiler;"); + mv.visitInsn($Opcodes.RETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } diff --git a/modules/API/src/main/java/com/comphenix/protocol/wrappers/nbt/TileEntityAccessor.java b/modules/API/src/main/java/com/comphenix/protocol/wrappers/nbt/TileEntityAccessor.java index db3ffd80..594850c1 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/wrappers/nbt/TileEntityAccessor.java +++ b/modules/API/src/main/java/com/comphenix/protocol/wrappers/nbt/TileEntityAccessor.java @@ -4,25 +4,24 @@ import java.io.IOException; import java.lang.reflect.Method; import java.util.concurrent.ConcurrentMap; -import net.sf.cglib.asm.ClassReader; -import net.sf.cglib.asm.MethodVisitor; -import net.sf.cglib.asm.Opcodes; +import com.comphenix.protocol.reflect.FuzzyReflection; +import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.reflect.accessors.FieldAccessor; +import com.comphenix.protocol.reflect.accessors.MethodAccessor; +import com.comphenix.protocol.utility.EnhancerFactory; +import com.comphenix.protocol.utility.MinecraftReflection; +import com.google.common.collect.Maps; + +import net.sf.cglib.asm.$ClassReader; +import net.sf.cglib.asm.$ClassVisitor; +import net.sf.cglib.asm.$MethodVisitor; +import net.sf.cglib.asm.$Opcodes; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import org.bukkit.block.BlockState; -import com.comphenix.protocol.reflect.FuzzyReflection; -import com.comphenix.protocol.reflect.accessors.Accessors; -import com.comphenix.protocol.reflect.accessors.FieldAccessor; -import com.comphenix.protocol.reflect.accessors.MethodAccessor; -import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor; -import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor; -import com.comphenix.protocol.utility.EnhancerFactory; -import com.comphenix.protocol.utility.MinecraftReflection; -import com.google.common.collect.Maps; - /** * Manipulate tile entities. * @author Kristian @@ -90,26 +89,26 @@ class TileEntityAccessor { private void findMethodsUsingASM() throws IOException { final Class nbtCompoundClass = MinecraftReflection.getNBTCompoundClass(); final Class tileEntityClass = MinecraftReflection.getTileEntityClass(); - final ClassReader reader = new ClassReader(tileEntityClass.getCanonicalName()); + final $ClassReader reader = new $ClassReader(tileEntityClass.getCanonicalName()); final String tagCompoundName = getJarName(MinecraftReflection.getNBTCompoundClass()); final String expectedDesc = "(L" + tagCompoundName + ";)"; - reader.accept(new EmptyClassVisitor() { + reader.accept(new $ClassVisitor($Opcodes.ASM5) { @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + public $MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { final String methodName = name; // Detect read/write calls to NBTTagCompound if (desc.startsWith(expectedDesc)) { - return new EmptyMethodVisitor() { + return new $MethodVisitor($Opcodes.ASM5) { private int readMethods; private int writeMethods; @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean intf) { // This must be a virtual call on NBTTagCompound that accepts a String - if (opcode == Opcodes.INVOKEVIRTUAL + if (opcode == $Opcodes.INVOKEVIRTUAL && tagCompoundName.equals(owner) && desc.startsWith("(Ljava/lang/String")) { diff --git a/modules/ProtocolLib/pom.xml b/modules/ProtocolLib/pom.xml index ac224fec..b6ad5ba5 100644 --- a/modules/ProtocolLib/pom.xml +++ b/modules/ProtocolLib/pom.xml @@ -20,6 +20,8 @@ UTF-8 ${project.version} + + 1.7.0RC4 @@ -238,25 +240,25 @@ junit junit - 4.10 + 4.12 test org.mockito - mockito-all - 1.8.4 + mockito-core + 2.8.9 test org.powermock powermock-module-junit4 - 1.5 + ${powermock.version} test org.powermock - powermock-api-mockito - 1.5 + powermock-api-mockito2 + ${powermock.version} test diff --git a/modules/ProtocolLib/src/test/java/com/comphenix/protocol/wrappers/WrappedWatchableObjectTest.java b/modules/ProtocolLib/src/test/java/com/comphenix/protocol/wrappers/WrappedWatchableObjectTest.java deleted file mode 100644 index 1c82ec64..00000000 --- a/modules/ProtocolLib/src/test/java/com/comphenix/protocol/wrappers/WrappedWatchableObjectTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.comphenix.protocol.wrappers; - -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PowerMockIgnore; - -import com.comphenix.protocol.BukkitInitialization; - -@RunWith(org.powermock.modules.junit4.PowerMockRunner.class) -@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" }) -//@PrepareForTest(CraftItemFactory.class) -public class WrappedWatchableObjectTest { - //@BeforeClass - public static void initializeBukkit() throws IllegalAccessException { - BukkitInitialization.initializeItemMeta(); - } - - //@Test - /* public void testItemStack() { - final ItemStack stack = new ItemStack(Material.GOLD_AXE); - final WrappedWatchableObject test = new WrappedWatchableObject(0, stack); - - ItemStack value = (ItemStack) test.getValue(); - assertEquals(value.getType(), stack.getType()); - } */ -} diff --git a/pom.xml b/pom.xml index 9ff2037e..ddf7b5dd 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ UTF-8 - 4.3.0 + 4.3.1-SNAPSHOT 1.12-R0.1-SNAPSHOT @@ -67,7 +67,7 @@ cglib cglib-nodep - 2.2.2 + 3.2.5 compile