下面列出了org.springframework.core.annotation.MergedAnnotations#org.springframework.asm.Type 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void generateGet(Class type, final Map<String, PropertyDescriptor> getters) {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null);
e.load_arg(0);
e.checkcast(Type.getType(type));
e.load_arg(1);
e.checkcast(Constants.TYPE_STRING);
EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
@Override
public void processCase(Object key, Label end) {
PropertyDescriptor pd = getters.get(key);
MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod());
e.invoke(method);
e.box(method.getSignature().getReturnType());
e.return_value();
}
@Override
public void processDefault() {
e.aconst_null();
e.return_value();
}
});
e.end_method();
}
private void generateGetPropertyType(final Map allProps, String[] allNames) {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null);
e.load_arg(0);
EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
@Override
public void processCase(Object key, Label end) {
PropertyDescriptor pd = (PropertyDescriptor) allProps.get(key);
EmitUtils.load_class(e, Type.getType(pd.getPropertyType()));
e.return_value();
}
@Override
public void processDefault() {
e.aconst_null();
e.return_value();
}
});
e.end_method();
}
public static ClassInfo getClassInfo(final Class clazz) {
final Type type = Type.getType(clazz);
final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass());
return new ClassInfo() {
public Type getType() {
return type;
}
public Type getSuperType() {
return sc;
}
public Type[] getInterfaces() {
return TypeUtils.getTypes(clazz.getInterfaces());
}
public int getModifiers() {
return clazz.getModifiers();
}
};
}
@Override
public String toString() {
String value = this.toStringValue;
if (value == null) {
StringBuilder builder = new StringBuilder();
builder.append(this.declaringClassName);
builder.append(".");
builder.append(this.name);
Type[] argumentTypes = Type.getArgumentTypes(this.descriptor);
builder.append("(");
for (Type type : argumentTypes) {
builder.append(type.getClassName());
}
builder.append(")");
value = builder.toString();
this.toStringValue = value;
}
return value;
}
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
getLeftOperand().generateCode(mv, cf);
CodeFlow.insertBoxIfNecessary(mv, cf.lastDescriptor());
Assert.state(this.type != null, "No type available");
if (this.type.isPrimitive()) {
// always false - but left operand code always driven
// in case it had side effects
mv.visitInsn(POP);
mv.visitInsn(ICONST_0); // value of false
}
else {
mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(this.type));
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
public static ClassInfo getClassInfo(final Class clazz) {
final Type type = Type.getType(clazz);
final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass());
return new ClassInfo() {
public Type getType() {
return type;
}
public Type getSuperType() {
return sc;
}
public Type[] getInterfaces() {
return TypeUtils.getTypes(clazz.getInterfaces());
}
public int getModifiers() {
return clazz.getModifiers();
}
};
}
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
getLeftOperand().generateCode(mv, cf);
CodeFlow.insertBoxIfNecessary(mv, cf.lastDescriptor());
Assert.state(this.type != null, "No type available");
if (this.type.isPrimitive()) {
// always false - but left operand code always driven
// in case it had side effects
mv.visitInsn(POP);
mv.visitInsn(ICONST_0); // value of false
}
else {
mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(this.type));
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
private void generatePut(Class type, final Map<String, PropertyDescriptor> setters) {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_PUT, null);
e.load_arg(0);
e.checkcast(Type.getType(type));
e.load_arg(1);
e.checkcast(Constants.TYPE_STRING);
EmitUtils.string_switch(e, getNames(setters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
@Override
public void processCase(Object key, Label end) {
PropertyDescriptor pd = setters.get(key);
if (pd.getReadMethod() == null) {
e.aconst_null();
} else {
MethodInfo read = ReflectUtils.getMethodInfo(pd.getReadMethod());
e.dup();
e.invoke(read);
e.box(read.getSignature().getReturnType());
}
// move old value behind bean
e.swap();
// new value
e.load_arg(2);
MethodInfo write = ReflectUtils.getMethodInfo(pd.getWriteMethod());
e.unbox(write.getSignature().getArgumentTypes()[0]);
e.invoke(write);
e.return_value();
}
@Override
public void processDefault() {
// fall-through
}
});
e.aconst_null();
e.return_value();
e.end_method();
}
@Override
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
ClassEmitterTransformer transformer = new ClassEmitterTransformer() {
@Override
public void end_class() {
declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null);
super.end_class();
}
};
return new TransformingClassGenerator(cg, transformer);
}
public Object newInstance(String type,
String[] interfaces,
WeakCacheKey<CallbackFilter> filter,
Type[] callbackTypes,
boolean useFactory,
boolean interceptDuringConstruction,
Long serialVersionUID);
private void validate() {
if (classOnly ^ (callbacks == null)) {
if (classOnly) {
throw new IllegalStateException("createClass does not accept callbacks");
}
else {
throw new IllegalStateException("Callbacks are required");
}
}
if (classOnly && (callbackTypes == null)) {
throw new IllegalStateException("Callback types are required");
}
if (validateCallbackTypes) {
callbackTypes = null;
}
if (callbacks != null && callbackTypes != null) {
if (callbacks.length != callbackTypes.length) {
throw new IllegalStateException("Lengths of callback and callback types array must be the same");
}
Type[] check = CallbackInfo.determineTypes(callbacks);
for (int i = 0; i < check.length; i++) {
if (!check[i].equals(callbackTypes[i])) {
throw new IllegalStateException("Callback " + check[i] + " is not assignable to " + callbackTypes[i]);
}
}
}
else if (callbacks != null) {
callbackTypes = CallbackInfo.determineTypes(callbacks);
}
if (interfaces != null) {
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i] == null) {
throw new IllegalStateException("Interfaces cannot be null");
}
if (!interfaces[i].isInterface()) {
throw new IllegalStateException(interfaces[i] + " is not an interface");
}
}
}
}
private void emitNewInstanceCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
Type thisType = getThisType(e);
e.load_arg(0);
e.invoke_static(thisType, SET_THREAD_CALLBACKS);
emitCommonNewInstance(e);
}
private Type getThisType(CodeEmitter e) {
if (currentData == null) {
return e.getClassEmitter().getClassType();
}
else {
return Type.getType(currentData.generatedClass);
}
}
private void emitCommonNewInstance(CodeEmitter e) {
Type thisType = getThisType(e);
e.new_instance(thisType);
e.dup();
e.invoke_constructor(thisType);
e.aconst_null();
e.invoke_static(thisType, SET_THREAD_CALLBACKS);
e.return_value();
e.end_method();
}
private void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, MULTIARG_NEW_INSTANCE, null);
final Type thisType = getThisType(e);
e.load_arg(2);
e.invoke_static(thisType, SET_THREAD_CALLBACKS);
e.new_instance(thisType);
e.dup();
e.load_arg(0);
EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) {
MethodInfo constructor = (MethodInfo) key;
Type types[] = constructor.getSignature().getArgumentTypes();
for (int i = 0; i < types.length; i++) {
e.load_arg(1);
e.push(i);
e.aaload();
e.unbox(types[i]);
}
e.invoke_constructor(thisType, constructor.getSignature());
e.goTo(end);
}
public void processDefault() {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found");
}
});
e.aconst_null();
e.invoke_static(thisType, SET_THREAD_CALLBACKS);
e.return_value();
e.end_method();
}
@Override
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
String className = Type.getType(desc).getClassName();
this.methodMetadataSet.add(this);
return new AnnotationAttributesReadingVisitor(
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
}
private static int[] computeLvtSlotIndices(boolean isStatic, Type[] paramTypes) {
int[] lvtIndex = new int[paramTypes.length];
int nextIndex = (isStatic ? 0 : 1);
for (int i = 0; i < paramTypes.length; i++) {
lvtIndex[i] = nextIndex;
if (isWideType(paramTypes[i])) {
nextIndex += 2;
}
else {
nextIndex++;
}
}
return lvtIndex;
}
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
// TODO Future optimization - if followed by a static method call, skip generating code here
if (this.type.isPrimitive()) {
if (this.type == Integer.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Boolean.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Byte.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Short.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Double.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Character.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Float.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Long.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
}
else if (this.type == Boolean.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
}
}
else {
mv.visitLdcInsn(Type.getType(this.type));
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
public static Signature getSignature(Member member) {
if (member instanceof Method) {
return new Signature(member.getName(), Type.getMethodDescriptor((Method) member));
}
else if (member instanceof Constructor) {
Type[] types = TypeUtils.getTypes(((Constructor) member).getParameterTypes());
return new Signature(Constants.CONSTRUCTOR_NAME,
Type.getMethodDescriptor(Type.VOID_TYPE, types));
}
else {
throw new IllegalArgumentException("Cannot get signature of a field");
}
}
public static MethodInfo getMethodInfo(final Member member, final int modifiers) {
final Signature sig = getSignature(member);
return new MethodInfo() {
private ClassInfo ci;
public ClassInfo getClassInfo() {
if (ci == null)
ci = ReflectUtils.getClassInfo(member.getDeclaringClass());
return ci;
}
public int getModifiers() {
return modifiers;
}
public Signature getSignature() {
return sig;
}
public Type[] getExceptionTypes() {
return ReflectUtils.getExceptionTypes(member);
}
public Attribute getAttribute() {
return null;
}
};
}
public static Method[] findMethods(String[] namesAndDescriptors, Method[] methods) {
Map map = new HashMap();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
map.put(method.getName() + Type.getMethodDescriptor(method), method);
}
Method[] result = new Method[namesAndDescriptors.length / 2];
for (int i = 0; i < result.length; i++) {
result[i] = (Method) map.get(namesAndDescriptors[i * 2] + namesAndDescriptors[i * 2 + 1]);
if (result[i] == null) {
// TODO: error?
}
}
return result;
}
public LocalVariableTableVisitor(Class<?> clazz, Map<Member, String[]> map, String name, String desc, boolean isStatic) {
super(SpringAsmInfo.ASM_VERSION);
this.clazz = clazz;
this.memberMap = map;
this.name = name;
this.args = Type.getArgumentTypes(desc);
this.parameterNames = new String[this.args.length];
this.isStatic = isStatic;
this.lvtSlotIndex = computeLvtSlotIndices(isStatic, this.args);
}
private static int[] computeLvtSlotIndices(boolean isStatic, Type[] paramTypes) {
int[] lvtIndex = new int[paramTypes.length];
int nextIndex = (isStatic ? 0 : 1);
for (int i = 0; i < paramTypes.length; i++) {
lvtIndex[i] = nextIndex;
if (isWideType(paramTypes[i])) {
nextIndex += 2;
}
else {
nextIndex++;
}
}
return lvtIndex;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// Skip bridge methods - we're only interested in original annotation-defining user methods.
// On JDK 8, we'd otherwise run into double detection of the same annotated method...
if ((access & Opcodes.ACC_BRIDGE) != 0) {
return super.visitMethod(access, name, desc, signature, exceptions);
}
return new MethodMetadataReadingVisitor(name, access, getClassName(),
Type.getReturnType(desc).getClassName(), this.classLoader, this.methodMetadataSet);
}
@Override
@Nullable
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (!visible) {
return null;
}
String className = Type.getType(desc).getClassName();
if (AnnotationUtils.isInJavaLangAnnotationPackage(className)) {
return null;
}
this.annotationSet.add(className);
return new AnnotationAttributesReadingVisitor(
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
}
@Override
public void visit(String name, Object value) {
if (value instanceof Type) {
value = ((Type) value).getClassName();
}
this.attributes.put(name, value);
}
@Override
public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) {
String annotationType = Type.getType(asmTypeDescriptor).getClassName();
AnnotationAttributes nestedAttributes = new AnnotationAttributes();
this.allNestedAttributes.add(nestedAttributes);
return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// Skip bridge methods - we're only interested in original annotation-defining user methods.
// On JDK 8, we'd otherwise run into double detection of the same annotated method...
if ((access & Opcodes.ACC_BRIDGE) != 0) {
return super.visitMethod(access, name, desc, signature, exceptions);
}
return new MethodMetadataReadingVisitor(name, access, getClassName(),
Type.getReturnType(desc).getClassName(), this.classLoader, this.methodMetadataSet);
}
@Override
public void visit(String name, Object value) {
if (value instanceof Type) {
value = ((Type) value).getClassName();
}
this.elements.add(value);
}
@Override
public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) {
String annotationType = Type.getType(asmTypeDescriptor).getClassName();
AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader);
this.attributes.put(attributeName, nestedAttributes);
return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader);
}