Update dependency versions to hopefully work with Java 9
Dieser Commit ist enthalten in:
Ursprung
adb3c5392c
Commit
20d78832b0
@ -4,16 +4,11 @@ import java.io.IOException;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.List;
|
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.ClassAnalyser.AsmMethod.AsmOpcodes;
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
|
||||||
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.sf.cglib.asm.*;
|
||||||
|
|
||||||
public class ClassAnalyser {
|
public class ClassAnalyser {
|
||||||
/**
|
/**
|
||||||
* Represents a method in ASM.
|
* Represents a method in ASM.
|
||||||
@ -31,11 +26,11 @@ public class ClassAnalyser {
|
|||||||
|
|
||||||
public static AsmOpcodes fromIntOpcode(int opcode) {
|
public static AsmOpcodes fromIntOpcode(int opcode) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Opcodes.INVOKEVIRTUAL: return AsmOpcodes.INVOKE_VIRTUAL;
|
case $Opcodes.INVOKEVIRTUAL: return AsmOpcodes.INVOKE_VIRTUAL;
|
||||||
case Opcodes.INVOKESPECIAL: return AsmOpcodes.INVOKE_SPECIAL;
|
case $Opcodes.INVOKESPECIAL: return AsmOpcodes.INVOKE_SPECIAL;
|
||||||
case Opcodes.INVOKESTATIC: return AsmOpcodes.INVOKE_STATIC;
|
case $Opcodes.INVOKESTATIC: return AsmOpcodes.INVOKE_STATIC;
|
||||||
case Opcodes.INVOKEINTERFACE: return AsmOpcodes.INVOKE_INTERFACE;
|
case $Opcodes.INVOKEINTERFACE: return AsmOpcodes.INVOKE_INTERFACE;
|
||||||
case Opcodes.INVOKEDYNAMIC: return AsmOpcodes.INVOKE_DYNAMIC;
|
case $Opcodes.INVOKEDYNAMIC: return AsmOpcodes.INVOKE_DYNAMIC;
|
||||||
default: throw new IllegalArgumentException("Unknown opcode: " + opcode);
|
default: throw new IllegalArgumentException("Unknown opcode: " + opcode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,30 +104,29 @@ public class ClassAnalyser {
|
|||||||
* @return The method calls.
|
* @return The method calls.
|
||||||
* @throws IOException Cannot access the parent class.
|
* @throws IOException Cannot access the parent class.
|
||||||
*/
|
*/
|
||||||
public List<AsmMethod> getMethodCalls(Class<?> clazz, Method method) throws IOException {
|
private List<AsmMethod> getMethodCalls(Class<?> clazz, Method method) throws IOException {
|
||||||
final ClassReader reader = new ClassReader(clazz.getCanonicalName());
|
final $ClassReader reader = new $ClassReader(clazz.getCanonicalName());
|
||||||
final List<AsmMethod> output = Lists.newArrayList();
|
final List<AsmMethod> output = Lists.newArrayList();
|
||||||
|
|
||||||
// The method we are looking for
|
// The method we are looking for
|
||||||
final String methodName = method.getName();
|
final String methodName = method.getName();
|
||||||
final String methodDescription = Type.getMethodDescriptor(method);
|
final String methodDescription = $Type.getMethodDescriptor(method);
|
||||||
|
|
||||||
reader.accept(new EmptyClassVisitor() {
|
reader.accept(new $ClassVisitor($Opcodes.ASM5) {
|
||||||
@Override
|
@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) {
|
||||||
// Check method
|
|
||||||
if (methodName.equals(name) && methodDescription.equals(desc)) {
|
if (methodName.equals(name) && methodDescription.equals(desc)) {
|
||||||
return new EmptyMethodVisitor() {
|
return new $MethodVisitor($Opcodes.ASM5) {
|
||||||
@Override
|
@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));
|
output.add(new AsmMethod(AsmOpcodes.fromIntOpcode(opcode), owner, methodName, desc));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}, $ClassReader.EXPAND_FRAMES);
|
||||||
}, ClassReader.EXPAND_FRAMES);
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,25 +17,25 @@
|
|||||||
|
|
||||||
package com.comphenix.protocol.reflect.compiler;
|
package com.comphenix.protocol.reflect.compiler;
|
||||||
|
|
||||||
import net.sf.cglib.asm.MethodVisitor;
|
import net.sf.cglib.asm.$MethodVisitor;
|
||||||
import net.sf.cglib.asm.Opcodes;
|
import net.sf.cglib.asm.$Opcodes;
|
||||||
import net.sf.cglib.asm.Type;
|
import net.sf.cglib.asm.$Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by the compiler to automatically box and unbox values.
|
* Used by the compiler to automatically box and unbox values.
|
||||||
*/
|
*/
|
||||||
class BoxingHelper {
|
class BoxingHelper {
|
||||||
|
|
||||||
private final static Type BYTE_TYPE = Type.getObjectType("java/lang/Byte");
|
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 BOOLEAN_$Type = $Type.getObjectType("java/lang/Boolean");
|
||||||
private final static Type SHORT_TYPE = Type.getObjectType("java/lang/Short");
|
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 CHARACTER_$Type = $Type.getObjectType("java/lang/Character");
|
||||||
private final static Type INTEGER_TYPE = Type.getObjectType("java/lang/Integer");
|
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 FLOAT_$Type = $Type.getObjectType("java/lang/Float");
|
||||||
private final static Type LONG_TYPE = Type.getObjectType("java/lang/Long");
|
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 DOUBLE_$Type = $Type.getObjectType("java/lang/Double");
|
||||||
private final static Type NUMBER_TYPE = Type.getObjectType("java/lang/Number");
|
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 OBJECT_$Type = $Type.getObjectType("java/lang/Object");
|
||||||
|
|
||||||
private final static MethodDescriptor BOOLEAN_VALUE = MethodDescriptor.getMethod("boolean booleanValue()");
|
private final static MethodDescriptor BOOLEAN_VALUE = MethodDescriptor.getMethod("boolean booleanValue()");
|
||||||
private final static MethodDescriptor CHAR_VALUE = MethodDescriptor.getMethod("char charValue()");
|
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 LONG_VALUE = MethodDescriptor.getMethod("long longValue()");
|
||||||
private final static MethodDescriptor DOUBLE_VALUE = MethodDescriptor.getMethod("double doubleValue()");
|
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;
|
this.mv = mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,42 +54,42 @@ class BoxingHelper {
|
|||||||
* Generates the instructions to box the top stack value. This value is
|
* Generates the instructions to box the top stack value. This value is
|
||||||
* replaced by its boxed equivalent on top of the stack.
|
* 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){
|
public void box(final $Type type){
|
||||||
if(type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
if(type.getSort() == $Type.OBJECT || type.getSort() == $Type.ARRAY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == Type.VOID_TYPE) {
|
if(type == $Type.VOID_TYPE) {
|
||||||
push((String) null);
|
push((String) null);
|
||||||
} else {
|
} else {
|
||||||
Type boxed = type;
|
$Type boxed = type;
|
||||||
|
|
||||||
switch(type.getSort()) {
|
switch(type.getSort()) {
|
||||||
case Type.BYTE:
|
case $Type.BYTE:
|
||||||
boxed = BYTE_TYPE;
|
boxed = BYTE_$Type;
|
||||||
break;
|
break;
|
||||||
case Type.BOOLEAN:
|
case $Type.BOOLEAN:
|
||||||
boxed = BOOLEAN_TYPE;
|
boxed = BOOLEAN_$Type;
|
||||||
break;
|
break;
|
||||||
case Type.SHORT:
|
case $Type.SHORT:
|
||||||
boxed = SHORT_TYPE;
|
boxed = SHORT_$Type;
|
||||||
break;
|
break;
|
||||||
case Type.CHAR:
|
case $Type.CHAR:
|
||||||
boxed = CHARACTER_TYPE;
|
boxed = CHARACTER_$Type;
|
||||||
break;
|
break;
|
||||||
case Type.INT:
|
case $Type.INT:
|
||||||
boxed = INTEGER_TYPE;
|
boxed = INTEGER_$Type;
|
||||||
break;
|
break;
|
||||||
case Type.FLOAT:
|
case $Type.FLOAT:
|
||||||
boxed = FLOAT_TYPE;
|
boxed = FLOAT_$Type;
|
||||||
break;
|
break;
|
||||||
case Type.LONG:
|
case $Type.LONG:
|
||||||
boxed = LONG_TYPE;
|
boxed = LONG_$Type;
|
||||||
break;
|
break;
|
||||||
case Type.DOUBLE:
|
case $Type.DOUBLE:
|
||||||
boxed = DOUBLE_TYPE;
|
boxed = DOUBLE_$Type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,46 +105,46 @@ class BoxingHelper {
|
|||||||
swap();
|
swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeConstructor(boxed, new MethodDescriptor("<init>", Type.VOID_TYPE, new Type[] {type}));
|
invokeConstructor(boxed, new MethodDescriptor("<init>", $Type.VOID_TYPE, new $Type[] {type}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the instruction to invoke a constructor.
|
* 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.
|
* @param method the constructor to be invoked.
|
||||||
*/
|
*/
|
||||||
public void invokeConstructor(final Type type, final MethodDescriptor method){
|
public void invokeConstructor(final $Type $Type, final MethodDescriptor method){
|
||||||
invokeInsn(Opcodes.INVOKESPECIAL, type, method);
|
invokeInsn($Opcodes.INVOKESPECIAL, $Type, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a DUP_X1 instruction.
|
* Generates a DUP_X1 instruction.
|
||||||
*/
|
*/
|
||||||
public void dupX1(){
|
public void dupX1(){
|
||||||
mv.visitInsn(Opcodes.DUP_X1);
|
mv.visitInsn($Opcodes.DUP_X1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a DUP_X2 instruction.
|
* Generates a DUP_X2 instruction.
|
||||||
*/
|
*/
|
||||||
public void dupX2(){
|
public void dupX2(){
|
||||||
mv.visitInsn(Opcodes.DUP_X2);
|
mv.visitInsn($Opcodes.DUP_X2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a POP instruction.
|
* Generates a POP instruction.
|
||||||
*/
|
*/
|
||||||
public void pop(){
|
public void pop(){
|
||||||
mv.visitInsn(Opcodes.POP);
|
mv.visitInsn($Opcodes.POP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a SWAP instruction.
|
* Generates a SWAP instruction.
|
||||||
*/
|
*/
|
||||||
public void swap(){
|
public void swap(){
|
||||||
mv.visitInsn(Opcodes.SWAP);
|
mv.visitInsn($Opcodes.SWAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,11 +163,11 @@ class BoxingHelper {
|
|||||||
*/
|
*/
|
||||||
public void push(final int value) {
|
public void push(final int value) {
|
||||||
if (value >= -1 && value <= 5) {
|
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) {
|
} 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) {
|
} else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
|
||||||
mv.visitIntInsn(Opcodes.SIPUSH, value);
|
mv.visitIntInsn($Opcodes.SIPUSH, value);
|
||||||
} else {
|
} else {
|
||||||
mv.visitLdcInsn(new Integer(value));
|
mv.visitLdcInsn(new Integer(value));
|
||||||
}
|
}
|
||||||
@ -176,10 +176,10 @@ class BoxingHelper {
|
|||||||
/**
|
/**
|
||||||
* Generates the instruction to create a new object.
|
* 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){
|
public void newInstance(final $Type $Type){
|
||||||
typeInsn(Opcodes.NEW, type);
|
$TypeInsn($Opcodes.NEW, $Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,7 +189,7 @@ class BoxingHelper {
|
|||||||
*/
|
*/
|
||||||
public void push(final String value) {
|
public void push(final String value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
mv.visitInsn(Opcodes.ACONST_NULL);
|
mv.visitInsn($Opcodes.ACONST_NULL);
|
||||||
} else {
|
} else {
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
@ -200,35 +200,35 @@ class BoxingHelper {
|
|||||||
* replaced by its unboxed equivalent on top of the stack.
|
* replaced by its unboxed equivalent on top of the stack.
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* the type of the top stack value.
|
* the $Type of the top stack value.
|
||||||
*/
|
*/
|
||||||
public void unbox(final Type type){
|
public void unbox(final $Type type){
|
||||||
Type t = NUMBER_TYPE;
|
$Type t = NUMBER_$Type;
|
||||||
MethodDescriptor sig = null;
|
MethodDescriptor sig = null;
|
||||||
|
|
||||||
switch(type.getSort()) {
|
switch(type.getSort()) {
|
||||||
case Type.VOID:
|
case $Type.VOID:
|
||||||
return;
|
return;
|
||||||
case Type.CHAR:
|
case $Type.CHAR:
|
||||||
t = CHARACTER_TYPE;
|
t = CHARACTER_$Type;
|
||||||
sig = CHAR_VALUE;
|
sig = CHAR_VALUE;
|
||||||
break;
|
break;
|
||||||
case Type.BOOLEAN:
|
case $Type.BOOLEAN:
|
||||||
t = BOOLEAN_TYPE;
|
t = BOOLEAN_$Type;
|
||||||
sig = BOOLEAN_VALUE;
|
sig = BOOLEAN_VALUE;
|
||||||
break;
|
break;
|
||||||
case Type.DOUBLE:
|
case $Type.DOUBLE:
|
||||||
sig = DOUBLE_VALUE;
|
sig = DOUBLE_VALUE;
|
||||||
break;
|
break;
|
||||||
case Type.FLOAT:
|
case $Type.FLOAT:
|
||||||
sig = FLOAT_VALUE;
|
sig = FLOAT_VALUE;
|
||||||
break;
|
break;
|
||||||
case Type.LONG:
|
case $Type.LONG:
|
||||||
sig = LONG_VALUE;
|
sig = LONG_VALUE;
|
||||||
break;
|
break;
|
||||||
case Type.INT:
|
case $Type.INT:
|
||||||
case Type.SHORT:
|
case $Type.SHORT:
|
||||||
case Type.BYTE:
|
case $Type.BYTE:
|
||||||
sig = INT_VALUE;
|
sig = INT_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,13 +242,13 @@ class BoxingHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the instruction to check that the top stack value is of the
|
* 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){
|
public void checkCast(final $Type $Type){
|
||||||
if(!type.equals(OBJECT_TYPE)) {
|
if(!$Type.equals(OBJECT_$Type)) {
|
||||||
typeInsn(Opcodes.CHECKCAST, type);
|
$TypeInsn($Opcodes.CHECKCAST, $Type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,35 +258,35 @@ class BoxingHelper {
|
|||||||
* @param owner the class in which the method is defined.
|
* @param owner the class in which the method is defined.
|
||||||
* @param method the method to be invoked.
|
* @param method the method to be invoked.
|
||||||
*/
|
*/
|
||||||
public void invokeVirtual(final Type owner, final MethodDescriptor method){
|
public void invokeVirtual(final $Type owner, final MethodDescriptor method){
|
||||||
invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method);
|
invokeInsn($Opcodes.INVOKEVIRTUAL, owner, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an invoke method instruction.
|
* Generates an invoke method instruction.
|
||||||
*
|
*
|
||||||
* @param opcode the instruction's opcode.
|
* @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.
|
* @param method the method to be invoked.
|
||||||
*/
|
*/
|
||||||
private void invokeInsn(final int opcode, final Type type, final MethodDescriptor method){
|
private void invokeInsn(final int opcode, final $Type $Type, final MethodDescriptor method){
|
||||||
String owner = type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName();
|
String owner = $Type.getSort() == $Type.ARRAY ? $Type.getDescriptor() : $Type.getInternalName();
|
||||||
mv.visitMethodInsn(opcode, owner, method.getName(), method.getDescriptor());
|
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 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;
|
String desc;
|
||||||
|
|
||||||
if(type.getSort() == Type.ARRAY) {
|
if($Type.getSort() == $Type.ARRAY) {
|
||||||
desc = type.getDescriptor();
|
desc = $Type.getDescriptor();
|
||||||
} else {
|
} else {
|
||||||
desc = type.getInternalName();
|
desc = $Type.getInternalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitTypeInsn(opcode, desc);
|
mv.visitTypeInsn(opcode, desc);
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,7 +20,7 @@ package com.comphenix.protocol.reflect.compiler;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.sf.cglib.asm.Type;
|
import net.sf.cglib.asm.$Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a method.
|
* 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 name the method's name.
|
||||||
* @param desc the method's descriptor.
|
* @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 name the method's name.
|
||||||
* @param returnType the method's return type.
|
* @param returnType the method's return type.
|
||||||
@ -75,14 +75,14 @@ class MethodDescriptor {
|
|||||||
*/
|
*/
|
||||||
public MethodDescriptor(
|
public MethodDescriptor(
|
||||||
final String name,
|
final String name,
|
||||||
final Type returnType,
|
final $Type returnType,
|
||||||
final Type[] argumentTypes)
|
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.
|
* declaration.
|
||||||
*
|
*
|
||||||
* @param method a Java method declaration, without argument names, of the
|
* @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
|
* "java.util.List", ...). Classes of the java.lang package can be
|
||||||
* specified by their unqualified name; all other classes names must
|
* specified by their unqualified name; all other classes names must
|
||||||
* be fully qualified.
|
* be fully qualified.
|
||||||
* @return a {@link Method} corresponding to the given Java method
|
* @return a {@link MethodDescriptor} corresponding to the given Java method
|
||||||
* declaration.
|
* declaration.
|
||||||
* @throws IllegalArgumentException if <code>method</code> could not get
|
* @throws IllegalArgumentException if <code>method</code> could not get
|
||||||
* parsed.
|
* 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.
|
* declaration.
|
||||||
*
|
*
|
||||||
* @param method a Java method declaration, without argument names, of the
|
* @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.
|
* default package, or false if they correspond to java.lang classes.
|
||||||
* For instance "Object" means "Object" if this option is true, or
|
* For instance "Object" means "Object" if this option is true, or
|
||||||
* "java.lang.Object" otherwise.
|
* "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.
|
* declaration.
|
||||||
* @throws IllegalArgumentException if <code>method</code> could not get
|
* @throws IllegalArgumentException if <code>method</code> could not get
|
||||||
* parsed.
|
* parsed.
|
||||||
@ -134,7 +134,7 @@ class MethodDescriptor {
|
|||||||
}
|
}
|
||||||
String returnType = method.substring(0, space);
|
String returnType = method.substring(0, space);
|
||||||
String methodName = method.substring(space + 1, start - 1).trim();
|
String methodName = method.substring(space + 1, start - 1).trim();
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append('(');
|
sb.append('(');
|
||||||
int p;
|
int p;
|
||||||
do {
|
do {
|
||||||
@ -158,7 +158,7 @@ class MethodDescriptor {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while ((index = type.indexOf("[]", index) + 1) > 0) {
|
while ((index = type.indexOf("[]", index) + 1) > 0) {
|
||||||
sb.append('[');
|
sb.append('[');
|
||||||
@ -206,8 +206,8 @@ class MethodDescriptor {
|
|||||||
*
|
*
|
||||||
* @return the return type of the method described by this object.
|
* @return the return type of the method described by this object.
|
||||||
*/
|
*/
|
||||||
public Type getReturnType() {
|
public $Type getReturnType() {
|
||||||
return Type.getReturnType(desc);
|
return $Type.getReturnType(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,8 +215,8 @@ class MethodDescriptor {
|
|||||||
*
|
*
|
||||||
* @return the argument types of the method described by this object.
|
* @return the argument types of the method described by this object.
|
||||||
*/
|
*/
|
||||||
public Type[] getArgumentTypes() {
|
public $Type[] getArgumentTypes() {
|
||||||
return Type.getArgumentTypes(desc);
|
return $Type.getArgumentTypes(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -25,12 +25,12 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import net.sf.cglib.asm.ClassWriter;
|
import net.sf.cglib.asm.$ClassWriter;
|
||||||
import net.sf.cglib.asm.FieldVisitor;
|
import net.sf.cglib.asm.$FieldVisitor;
|
||||||
import net.sf.cglib.asm.Label;
|
import net.sf.cglib.asm.$Label;
|
||||||
import net.sf.cglib.asm.MethodVisitor;
|
import net.sf.cglib.asm.$MethodVisitor;
|
||||||
import net.sf.cglib.asm.Opcodes;
|
import net.sf.cglib.asm.$Opcodes;
|
||||||
import net.sf.cglib.asm.Type;
|
import net.sf.cglib.asm.$Type;
|
||||||
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
import com.comphenix.protocol.error.Report;
|
import com.comphenix.protocol.error.Report;
|
||||||
@ -276,15 +276,15 @@ public final class StructureCompiler {
|
|||||||
*/
|
*/
|
||||||
private <TField> Class<?> generateClass(StructureModifier<TField> source) {
|
private <TField> Class<?> generateClass(StructureModifier<TField> source) {
|
||||||
|
|
||||||
ClassWriter cw = new ClassWriter(0);
|
$ClassWriter cw = new $ClassWriter(0);
|
||||||
Class<?> targetType = source.getTargetType();
|
Class<?> targetType = source.getTargetType();
|
||||||
|
|
||||||
String className = getCompiledName(source);
|
String className = getCompiledName(source);
|
||||||
String targetSignature = Type.getDescriptor(targetType);
|
String targetSignature = $Type.getDescriptor(targetType);
|
||||||
String targetName = targetType.getName().replace('.', '/');
|
String targetName = targetType.getName().replace('.', '/');
|
||||||
|
|
||||||
// Define class
|
// 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);
|
null, COMPILED_CLASS, null);
|
||||||
|
|
||||||
createFields(cw, targetSignature);
|
createFields(cw, targetSignature);
|
||||||
@ -352,196 +352,196 @@ public final class StructureCompiler {
|
|||||||
return !Modifier.isFinal(field.getModifiers());
|
return !Modifier.isFinal(field.getModifiers());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createFields(ClassWriter cw, String targetSignature) {
|
private void createFields($ClassWriter cw, String targetSignature) {
|
||||||
FieldVisitor typedField = cw.visitField(Opcodes.ACC_PRIVATE, "typedTarget", targetSignature, null, null);
|
$FieldVisitor typedField = cw.visitField($Opcodes.ACC_PRIVATE, "typedTarget", targetSignature, null, null);
|
||||||
typedField.visitEnd();
|
typedField.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createWriteMethod(ClassWriter cw, String className, List<Field> fields, String targetSignature, String targetName) {
|
private void createWriteMethod($ClassWriter cw, String className, List<Field> fields, String targetSignature, String targetName) {
|
||||||
|
|
||||||
String methodDescriptor = "(ILjava/lang/Object;)L" + SUPER_CLASS + ";";
|
String methodDescriptor = "(ILjava/lang/Object;)L" + SUPER_CLASS + ";";
|
||||||
String methodSignature = "(ILjava/lang/Object;)L" + SUPER_CLASS + "<Ljava/lang/Object;>;";
|
String methodSignature = "(ILjava/lang/Object;)L" + SUPER_CLASS + "<Ljava/lang/Object;>;";
|
||||||
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 });
|
new String[] { FIELD_EXCEPTION_CLASS });
|
||||||
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
||||||
|
|
||||||
String generatedClassName = PACKAGE_NAME + "/" + className;
|
String generatedClassName = PACKAGE_NAME + "/" + className;
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature);
|
mv.visitFieldInsn($Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature);
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, 3);
|
mv.visitVarInsn($Opcodes.ASTORE, 3);
|
||||||
mv.visitVarInsn(Opcodes.ILOAD, 1);
|
mv.visitVarInsn($Opcodes.ILOAD, 1);
|
||||||
|
|
||||||
// The last label is for the default switch
|
// The last $Label is for the default switch
|
||||||
Label[] labels = new Label[fields.size()];
|
$Label[] $Labels = new $Label[fields.size()];
|
||||||
Label errorLabel = new Label();
|
$Label error$Label = new $Label();
|
||||||
Label returnLabel = new Label();
|
$Label return$Label = new $Label();
|
||||||
|
|
||||||
// Generate labels
|
// Generate $Labels
|
||||||
for (int i = 0; i < fields.size(); i++) {
|
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++) {
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
|
|
||||||
Field field = fields.get(i);
|
Field field = fields.get(i);
|
||||||
Class<?> outputType = field.getType();
|
Class<?> outputType = field.getType();
|
||||||
Class<?> inputType = Primitives.wrap(outputType);
|
Class<?> inputType = Primitives.wrap(outputType);
|
||||||
String typeDescriptor = Type.getDescriptor(outputType);
|
String typeDescriptor = $Type.getDescriptor(outputType);
|
||||||
String inputPath = inputType.getName().replace('.', '/');
|
String inputPath = inputType.getName().replace('.', '/');
|
||||||
|
|
||||||
mv.visitLabel(labels[i]);
|
mv.visitLabel($Labels[i]);
|
||||||
|
|
||||||
// Push the compare object
|
// Push the compare object
|
||||||
if (i == 0)
|
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
|
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
|
// Only write to public non-final fields
|
||||||
if (isPublic(field) && isNonFinal(field)) {
|
if (isPublic(field) && isNonFinal(field)) {
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 3);
|
mv.visitVarInsn($Opcodes.ALOAD, 3);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 2);
|
mv.visitVarInsn($Opcodes.ALOAD, 2);
|
||||||
|
|
||||||
if (!outputType.isPrimitive())
|
if (!outputType.isPrimitive())
|
||||||
mv.visitTypeInsn(Opcodes.CHECKCAST, inputPath);
|
mv.visitTypeInsn($Opcodes.CHECKCAST, inputPath);
|
||||||
else
|
else
|
||||||
boxingHelper.unbox(Type.getType(outputType));
|
boxingHelper.unbox($Type.getType(outputType));
|
||||||
|
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, targetName, field.getName(), typeDescriptor);
|
mv.visitFieldInsn($Opcodes.PUTFIELD, targetName, field.getName(), typeDescriptor);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Use reflection. We don't have a choice, unfortunately.
|
// Use reflection. We don't have a choice, unfortunately.
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitVarInsn(Opcodes.ILOAD, 1);
|
mv.visitVarInsn($Opcodes.ILOAD, 1);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 2);
|
mv.visitVarInsn($Opcodes.ALOAD, 2);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, generatedClassName, "writeReflected", "(ILjava/lang/Object;)V");
|
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.visitLabel(error$Label);
|
||||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null);
|
||||||
mv.visitTypeInsn(Opcodes.NEW, FIELD_EXCEPTION_CLASS);
|
mv.visitTypeInsn($Opcodes.NEW, FIELD_EXCEPTION_CLASS);
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn($Opcodes.DUP);
|
||||||
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
|
mv.visitTypeInsn($Opcodes.NEW, "java/lang/StringBuilder");
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn($Opcodes.DUP);
|
||||||
mv.visitLdcInsn("Invalid index ");
|
mv.visitLdcInsn("Invalid index ");
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
|
mv.visitMethodInsn($Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
|
||||||
mv.visitVarInsn(Opcodes.ILOAD, 1);
|
mv.visitVarInsn($Opcodes.ILOAD, 1);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;");
|
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.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "<init>", "(Ljava/lang/String;)V");
|
mv.visitMethodInsn($Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "<init>", "(Ljava/lang/String;)V");
|
||||||
mv.visitInsn(Opcodes.ATHROW);
|
mv.visitInsn($Opcodes.ATHROW);
|
||||||
|
|
||||||
mv.visitLabel(returnLabel);
|
mv.visitLabel(return$Label);
|
||||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitInsn(Opcodes.ARETURN);
|
mv.visitInsn($Opcodes.ARETURN);
|
||||||
mv.visitMaxs(5, 4);
|
mv.visitMaxs(5, 4);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createReadMethod(ClassWriter cw, String className, List<Field> fields, String targetSignature, String targetName) {
|
private void createReadMethod($ClassWriter cw, String className, List<Field> fields, String targetSignature, String targetName) {
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PROTECTED, "readGenerated", "(I)Ljava/lang/Object;", null,
|
$MethodVisitor mv = cw.visitMethod($Opcodes.ACC_PROTECTED, "readGenerated", "(I)Ljava/lang/Object;", null,
|
||||||
new String[] { "com/comphenix/protocol/reflect/FieldAccessException" });
|
new String[] { "com/comphenix/protocol/reflect/FieldAccessException" });
|
||||||
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
BoxingHelper boxingHelper = new BoxingHelper(mv);
|
||||||
|
|
||||||
String generatedClassName = PACKAGE_NAME + "/" + className;
|
String generatedClassName = PACKAGE_NAME + "/" + className;
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature);
|
mv.visitFieldInsn($Opcodes.GETFIELD, generatedClassName, "typedTarget", targetSignature);
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, 2);
|
mv.visitVarInsn($Opcodes.ASTORE, 2);
|
||||||
mv.visitVarInsn(Opcodes.ILOAD, 1);
|
mv.visitVarInsn($Opcodes.ILOAD, 1);
|
||||||
|
|
||||||
// The last label is for the default switch
|
// The last $Label is for the default switch
|
||||||
Label[] labels = new Label[fields.size()];
|
$Label[] $Labels = new $Label[fields.size()];
|
||||||
Label errorLabel = new Label();
|
$Label error$Label = new $Label();
|
||||||
|
|
||||||
// Generate labels
|
// Generate $Labels
|
||||||
for (int i = 0; i < fields.size(); i++) {
|
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++) {
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
|
|
||||||
Field field = fields.get(i);
|
Field field = fields.get(i);
|
||||||
Class<?> outputType = field.getType();
|
Class<?> outputType = field.getType();
|
||||||
String typeDescriptor = Type.getDescriptor(outputType);
|
String typeDescriptor = $Type.getDescriptor(outputType);
|
||||||
|
|
||||||
mv.visitLabel(labels[i]);
|
mv.visitLabel($Labels[i]);
|
||||||
|
|
||||||
// Push the compare object
|
// Push the compare object
|
||||||
if (i == 0)
|
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
|
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
|
// Note that byte code cannot access non-public fields
|
||||||
if (isPublic(field)) {
|
if (isPublic(field)) {
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 2);
|
mv.visitVarInsn($Opcodes.ALOAD, 2);
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, targetName, field.getName(), typeDescriptor);
|
mv.visitFieldInsn($Opcodes.GETFIELD, targetName, field.getName(), typeDescriptor);
|
||||||
|
|
||||||
boxingHelper.box(Type.getType(outputType));
|
boxingHelper.box($Type.getType(outputType));
|
||||||
} else {
|
} else {
|
||||||
// We have to use reflection for private and protected fields.
|
// We have to use reflection for private and protected fields.
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitVarInsn(Opcodes.ILOAD, 1);
|
mv.visitVarInsn($Opcodes.ILOAD, 1);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, generatedClassName, "readReflected", "(I)Ljava/lang/Object;");
|
mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, generatedClassName, "readReflected", "(I)Ljava/lang/Object;");
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitInsn(Opcodes.ARETURN);
|
mv.visitInsn($Opcodes.ARETURN);
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitLabel(errorLabel);
|
mv.visitLabel(error$Label);
|
||||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
mv.visitFrame($Opcodes.F_SAME, 0, null, 0, null);
|
||||||
mv.visitTypeInsn(Opcodes.NEW, FIELD_EXCEPTION_CLASS);
|
mv.visitTypeInsn($Opcodes.NEW, FIELD_EXCEPTION_CLASS);
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn($Opcodes.DUP);
|
||||||
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
|
mv.visitTypeInsn($Opcodes.NEW, "java/lang/StringBuilder");
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn($Opcodes.DUP);
|
||||||
mv.visitLdcInsn("Invalid index ");
|
mv.visitLdcInsn("Invalid index ");
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
|
mv.visitMethodInsn($Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
|
||||||
mv.visitVarInsn(Opcodes.ILOAD, 1);
|
mv.visitVarInsn($Opcodes.ILOAD, 1);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;");
|
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.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "<init>", "(Ljava/lang/String;)V");
|
mv.visitMethodInsn($Opcodes.INVOKESPECIAL, FIELD_EXCEPTION_CLASS, "<init>", "(Ljava/lang/String;)V");
|
||||||
mv.visitInsn(Opcodes.ATHROW);
|
mv.visitInsn($Opcodes.ATHROW);
|
||||||
mv.visitMaxs(5, 3);
|
mv.visitMaxs(5, 3);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createConstructor(ClassWriter cw, String className, String targetSignature, String targetName) {
|
private void createConstructor($ClassWriter cw, String className, String targetSignature, String targetName) {
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
|
$MethodVisitor mv = cw.visitMethod($Opcodes.ACC_PUBLIC, "<init>",
|
||||||
"(L" + SUPER_CLASS + ";L" + PACKAGE_NAME + "/StructureCompiler;)V",
|
"(L" + SUPER_CLASS + ";L" + PACKAGE_NAME + "/StructureCompiler;)V",
|
||||||
"(L" + SUPER_CLASS + "<Ljava/lang/Object;>;L" + PACKAGE_NAME + "/StructureCompiler;)V", null);
|
"(L" + SUPER_CLASS + "<Ljava/lang/Object;>;L" + PACKAGE_NAME + "/StructureCompiler;)V", null);
|
||||||
String fullClassName = PACKAGE_NAME + "/" + className;
|
String fullClassName = PACKAGE_NAME + "/" + className;
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, COMPILED_CLASS, "<init>", "()V");
|
mv.visitMethodInsn($Opcodes.INVOKESPECIAL, COMPILED_CLASS, "<init>", "()V");
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
mv.visitVarInsn($Opcodes.ALOAD, 1);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, fullClassName, "initialize", "(L" + SUPER_CLASS + ";)V");
|
mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, fullClassName, "initialize", "(L" + SUPER_CLASS + ";)V");
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
mv.visitVarInsn($Opcodes.ALOAD, 1);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SUPER_CLASS, "getTarget", "()Ljava/lang/Object;");
|
mv.visitMethodInsn($Opcodes.INVOKEVIRTUAL, SUPER_CLASS, "getTarget", "()Ljava/lang/Object;");
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, fullClassName, "target", "Ljava/lang/Object;");
|
mv.visitFieldInsn($Opcodes.PUTFIELD, fullClassName, "target", "Ljava/lang/Object;");
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, fullClassName, "target", "Ljava/lang/Object;");
|
mv.visitFieldInsn($Opcodes.GETFIELD, fullClassName, "target", "Ljava/lang/Object;");
|
||||||
mv.visitTypeInsn(Opcodes.CHECKCAST, targetName);
|
mv.visitTypeInsn($Opcodes.CHECKCAST, targetName);
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, fullClassName, "typedTarget", targetSignature);
|
mv.visitFieldInsn($Opcodes.PUTFIELD, fullClassName, "typedTarget", targetSignature);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn($Opcodes.ALOAD, 0);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 2);
|
mv.visitVarInsn($Opcodes.ALOAD, 2);
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, fullClassName, "compiler", "L" + PACKAGE_NAME + "/StructureCompiler;");
|
mv.visitFieldInsn($Opcodes.PUTFIELD, fullClassName, "compiler", "L" + PACKAGE_NAME + "/StructureCompiler;");
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn($Opcodes.RETURN);
|
||||||
mv.visitMaxs(2, 3);
|
mv.visitMaxs(2, 3);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
@ -4,25 +4,24 @@ import java.io.IOException;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import net.sf.cglib.asm.ClassReader;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import net.sf.cglib.asm.MethodVisitor;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import net.sf.cglib.asm.Opcodes;
|
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.Enhancer;
|
||||||
import net.sf.cglib.proxy.MethodInterceptor;
|
import net.sf.cglib.proxy.MethodInterceptor;
|
||||||
import net.sf.cglib.proxy.MethodProxy;
|
import net.sf.cglib.proxy.MethodProxy;
|
||||||
|
|
||||||
import org.bukkit.block.BlockState;
|
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.
|
* Manipulate tile entities.
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
@ -90,26 +89,26 @@ class TileEntityAccessor<T extends BlockState> {
|
|||||||
private void findMethodsUsingASM() throws IOException {
|
private void findMethodsUsingASM() throws IOException {
|
||||||
final Class<?> nbtCompoundClass = MinecraftReflection.getNBTCompoundClass();
|
final Class<?> nbtCompoundClass = MinecraftReflection.getNBTCompoundClass();
|
||||||
final Class<?> tileEntityClass = MinecraftReflection.getTileEntityClass();
|
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 tagCompoundName = getJarName(MinecraftReflection.getNBTCompoundClass());
|
||||||
final String expectedDesc = "(L" + tagCompoundName + ";)";
|
final String expectedDesc = "(L" + tagCompoundName + ";)";
|
||||||
|
|
||||||
reader.accept(new EmptyClassVisitor() {
|
reader.accept(new $ClassVisitor($Opcodes.ASM5) {
|
||||||
@Override
|
@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;
|
final String methodName = name;
|
||||||
|
|
||||||
// Detect read/write calls to NBTTagCompound
|
// Detect read/write calls to NBTTagCompound
|
||||||
if (desc.startsWith(expectedDesc)) {
|
if (desc.startsWith(expectedDesc)) {
|
||||||
return new EmptyMethodVisitor() {
|
return new $MethodVisitor($Opcodes.ASM5) {
|
||||||
private int readMethods;
|
private int readMethods;
|
||||||
private int writeMethods;
|
private int writeMethods;
|
||||||
|
|
||||||
@Override
|
@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
|
// This must be a virtual call on NBTTagCompound that accepts a String
|
||||||
if (opcode == Opcodes.INVOKEVIRTUAL
|
if (opcode == $Opcodes.INVOKEVIRTUAL
|
||||||
&& tagCompoundName.equals(owner)
|
&& tagCompoundName.equals(owner)
|
||||||
&& desc.startsWith("(Ljava/lang/String")) {
|
&& desc.startsWith("(Ljava/lang/String")) {
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.build.number></project.build.number>
|
<project.build.number></project.build.number>
|
||||||
<project.fullVersion>${project.version}</project.fullVersion>
|
<project.fullVersion>${project.version}</project.fullVersion>
|
||||||
|
|
||||||
|
<powermock.version>1.7.0RC4</powermock.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -238,25 +240,25 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.10</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-all</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>1.8.4</version>
|
<version>2.8.9</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.powermock</groupId>
|
<groupId>org.powermock</groupId>
|
||||||
<artifactId>powermock-module-junit4</artifactId>
|
<artifactId>powermock-module-junit4</artifactId>
|
||||||
<version>1.5</version>
|
<version>${powermock.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.powermock</groupId>
|
<groupId>org.powermock</groupId>
|
||||||
<artifactId>powermock-api-mockito</artifactId>
|
<artifactId>powermock-api-mockito2</artifactId>
|
||||||
<version>1.5</version>
|
<version>${powermock.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -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());
|
|
||||||
} */
|
|
||||||
}
|
|
4
pom.xml
4
pom.xml
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<minorVersion>4.3.0</minorVersion>
|
<minorVersion>4.3.1-SNAPSHOT</minorVersion>
|
||||||
<spigotVersion>1.12-R0.1-SNAPSHOT</spigotVersion>
|
<spigotVersion>1.12-R0.1-SNAPSHOT</spigotVersion>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@ -67,7 +67,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cglib</groupId>
|
<groupId>cglib</groupId>
|
||||||
<artifactId>cglib-nodep</artifactId>
|
<artifactId>cglib-nodep</artifactId>
|
||||||
<version>2.2.2</version>
|
<version>3.2.5</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren