use of soot.tagkit.AnnotationDefaultTag in project robovm by robovm.
the class AttributesEncoder method encodeAttributes.
private Constant encodeAttributes(Host host) {
List<Value> attributes = new ArrayList<Value>();
for (Tag tag : host.getTags()) {
if (tag instanceof SourceFileTag) {
// Skip. We don't need this at this time.
Value sourceFile = getString(((SourceFileTag) tag).getSourceFile());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), new IntegerConstant(SOURCE_FILE), sourceFile));
} else if (tag instanceof EnclosingMethodTag) {
EnclosingMethodTag emt = (EnclosingMethodTag) tag;
Value eClass = getString(emt.getEnclosingClass());
Value eMethod = getStringOrNull(emt.getEnclosingMethod());
Value eDesc = getStringOrNull(emt.getEnclosingMethodSig());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR), new IntegerConstant(ENCLOSING_METHOD), eClass, eMethod, eDesc));
} else if (tag instanceof SignatureTag) {
Value signature = getString(((SignatureTag) tag).getSignature());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), new IntegerConstant(SIGNATURE), signature));
} else if (tag instanceof InnerClassTag) {
InnerClassTag ict = (InnerClassTag) tag;
Value innerClass = getStringOrNull(ict.getInnerClass());
Value outerClass = getStringOrNull(ict.getOuterClass());
Value innerName = getStringOrNull(ict.getShortName());
Value innerClassAccess = new IntegerConstant(ict.getAccessFlags());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR, I32), new IntegerConstant(INNER_CLASS), innerClass, outerClass, innerName, innerClassAccess));
} else if (tag instanceof AnnotationDefaultTag) {
StructureConstant value = encodeAnnotationElementValue(((AnnotationDefaultTag) tag).getDefaultVal());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, value.getType()), new IntegerConstant(ANNOTATION_DEFAULT), value));
} else if (tag instanceof VisibilityAnnotationTag) {
VisibilityAnnotationTag vat = (VisibilityAnnotationTag) tag;
if (vat.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE) {
Type[] types = new Type[vat.getAnnotations().size()];
Value[] values = new Value[vat.getAnnotations().size()];
int i = 0;
for (AnnotationTag at : vat.getAnnotations()) {
values[i] = encodeAnnotationTagValue(at);
types[i] = values[i].getType();
i++;
}
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_ANNOTATIONS), new IntegerConstant(vat.getAnnotations().size()), new PackedStructureConstant(new PackedStructureType(types), values)));
}
} else if (tag instanceof VisibilityParameterAnnotationTag) {
VisibilityParameterAnnotationTag vpat = (VisibilityParameterAnnotationTag) tag;
List<Type> typesList = new ArrayList<Type>();
List<Value> valuesList = new ArrayList<Value>();
boolean hasRuntimeVisible = false;
for (VisibilityAnnotationTag vat : vpat.getVisibilityAnnotations()) {
typesList.add(I32);
if (vat.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE && vat.getAnnotations() != null && !vat.getAnnotations().isEmpty()) {
hasRuntimeVisible = true;
valuesList.add(new IntegerConstant(vat.getAnnotations().size()));
for (AnnotationTag at : vat.getAnnotations()) {
valuesList.add(encodeAnnotationTagValue(at));
typesList.add(valuesList.get(valuesList.size() - 1).getType());
}
} else {
valuesList.add(new IntegerConstant(0));
}
}
if (hasRuntimeVisible) {
Type[] types = typesList.toArray(new Type[typesList.size()]);
Value[] values = valuesList.toArray(new Value[valuesList.size()]);
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS), new IntegerConstant(vpat.getVisibilityAnnotations().size()), new PackedStructureConstant(new PackedStructureType(types), values)));
}
}
}
if (host instanceof SootMethod) {
List<SootClass> exceptions = ((SootMethod) host).getExceptions();
if (!exceptions.isEmpty()) {
Value[] values = new Value[exceptions.size()];
for (int i = 0; i < exceptions.size(); i++) {
String exName = getInternalName(exceptions.get(i));
values[i] = getString(exName);
addDependency(exName);
}
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new ArrayType(exceptions.size(), I8_PTR)), new IntegerConstant(EXCEPTIONS), new IntegerConstant(exceptions.size()), new ArrayConstant(new ArrayType(exceptions.size(), I8_PTR), values)));
}
}
if (attributes.isEmpty()) {
return null;
}
attributes.add(0, new IntegerConstant(attributes.size()));
Type[] types = new Type[attributes.size()];
for (int i = 0; i < types.length; i++) {
types[i] = attributes.get(i).getType();
}
return new PackedStructureConstant(new PackedStructureType(types), attributes.toArray(new Value[0]));
}
use of soot.tagkit.AnnotationDefaultTag in project robovm by robovm.
the class AnnotationImplPlugin method generateSetDefaultsMethod.
private void generateSetDefaultsMethod(Clazz clazz, ClassWriter cw) {
String implName = clazz.getInternalName() + IMPL_CLASS_NAME_SUFFIX;
SootClass sootClass = clazz.getSootClass();
List<SootMethod> methods = sootClass.getMethods();
// Generate the $setDefaults() method which is called from the constructor
// to set any default values
MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "$setDefaults", "()V", null, null);
mv.visitCode();
for (SootMethod method : methods) {
AnnotationDefaultTag defTag = (AnnotationDefaultTag) method.getTag(AnnotationDefaultTag.class.getSimpleName());
String fieldName = getFieldName(method);
if (defTag == null) {
// No default value. Set field to super.NO_VALUE.
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, BASE_CLASS, "NO_VALUE", "Ljava/lang/Object;");
mv.visitFieldInsn(PUTFIELD, implName, fieldName, "Ljava/lang/Object;");
} else {
soot.Type type = method.getReturnType();
String typeDesc = Types.getDescriptor(type);
Object v = null;
if (type instanceof PrimType) {
switch(typeDesc.charAt(0)) {
case 'Z':
case 'B':
case 'S':
case 'C':
case 'I':
v = ((AnnotationIntElem) defTag.getDefaultVal()).getValue();
break;
case 'J':
v = ((AnnotationLongElem) defTag.getDefaultVal()).getValue();
break;
case 'F':
v = ((AnnotationFloatElem) defTag.getDefaultVal()).getValue();
break;
case 'D':
v = ((AnnotationDoubleElem) defTag.getDefaultVal()).getValue();
break;
}
} else if ("Ljava/lang/Class;".equals(typeDesc)) {
v = Type.getType(((AnnotationClassElem) defTag.getDefaultVal()).getDesc());
if (((Type) v).getDescriptor().length() != 1) {
// Only use a simple LDC for primitive classes (e.g. byte.class).
// Other classes may not be available at runtime. By falling back
// to Method.getDefaultValue() below we will get the proper
// exception at runtime.
v = null;
}
} else if ("Ljava/lang/String;".equals(typeDesc)) {
v = ((AnnotationStringElem) defTag.getDefaultVal()).getValue();
}
if (v != null) {
mv.visitVarInsn(ALOAD, 0);
if (v instanceof Type && ((Type) v).getDescriptor().length() == 1) {
// LDC of primitive type class such as byte.class
switch(((Type) v).getDescriptor().charAt(0)) {
case 'V':
mv.visitFieldInsn(GETSTATIC, "java/lang/Void", "TYPE", "Ljava/lang/Class;");
break;
case 'Z':
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
break;
case 'B':
mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
break;
case 'S':
mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
break;
case 'C':
mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
break;
case 'I':
mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
break;
case 'J':
mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
break;
case 'F':
mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
break;
case 'D':
mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
break;
}
} else {
mv.visitLdcInsn(v);
}
boxIfNeeded(mv, type);
mv.visitFieldInsn(PUTFIELD, implName, fieldName, "Ljava/lang/Object;");
} else {
// Must be class, enum, array type or annotation. Fall back to super.getDefaultValue(<memberName>).
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(DUP);
mv.visitLdcInsn(method.getName());
mv.visitMethodInsn(INVOKESPECIAL, BASE_CLASS, "getDefaultValue", "(Ljava/lang/String;)Ljava/lang/Object;");
mv.visitFieldInsn(PUTFIELD, implName, fieldName, "Ljava/lang/Object;");
}
}
}
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
Aggregations