use of soot.tagkit.DeprecatedTag in project soot by Sable.
the class DexAnnotation method handleAnnotation.
/**
* @param annotations
* @return
*/
private List<Tag> handleAnnotation(Set<? extends org.jf.dexlib2.iface.Annotation> annotations, String classType) {
if (annotations == null || annotations.size() == 0)
return null;
List<Tag> tags = new ArrayList<Tag>();
// RUNTIME_VISIBLE,
VisibilityAnnotationTag[] vatg = new VisibilityAnnotationTag[3];
for (Annotation a : annotations) {
int v = getVisibility(a.getVisibility());
Tag t = null;
Type atype = DexType.toSoot(a.getType());
String atypes = atype.toString();
int eSize = a.getElements().size();
if (atypes.equals("dalvik.annotation.AnnotationDefault")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation Default. Got " + eSize + " instead.");
// get element
AnnotationElem e = getElements(a.getElements()).get(0);
AnnotationTag adt = new AnnotationTag(a.getType());
adt.addElem(e);
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
vatg[v].addAnnotation(adt);
} else if (atypes.equals("dalvik.annotation.EnclosingClass")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation EnclosingClass. Got " + eSize + " instead.");
for (AnnotationElement elem : a.getElements()) {
String outerClass = ((TypeEncodedValue) elem.getValue()).getValue();
outerClass = Util.dottedClassName(outerClass);
// repair it
if (outerClass.equals(clazz.getName())) {
if (outerClass.contains("$-")) {
/*
* This is a special case for generated lambda
* classes of jack and jill compiler. Generated
* lambda classes may contain '$' which do not
* indicate an inner/outer class separator if the
* '$' occurs after a inner class with a name
* starting with '-'. Thus we search for '$-' and
* anything after it including '-' is the inner
* classes name and anything before it is the outer
* classes name.
*/
outerClass = outerClass.substring(0, outerClass.indexOf("$-"));
} else if (outerClass.contains("$")) {
// remove everything after the last '$' including
// the last '$'
outerClass = outerClass.substring(0, outerClass.lastIndexOf("$"));
}
}
deps.typesToSignature.add(RefType.v(outerClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(outerClass));
assert clazz.getOuterClass() != clazz;
}
// annotation.
continue;
} else if (atypes.equals("dalvik.annotation.EnclosingMethod")) {
// ignore the annotation
if (eSize == 0)
continue;
// If the pointer is ambiguous, we are in trouble
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation EnclosingMethod. Got " + eSize + " instead.");
AnnotationStringElem e = (AnnotationStringElem) getElements(a.getElements()).get(0);
String[] split1 = e.getValue().split("\\ \\|");
String classString = split1[0];
String methodString = split1[1];
String parameters = split1[2];
String returnType = split1[3];
String methodSigString = "(" + parameters + ")" + returnType;
t = new EnclosingMethodTag(classString, methodString, methodSigString);
String outerClass = classString.replace("/", ".");
deps.typesToSignature.add(RefType.v(outerClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(outerClass));
assert clazz.getOuterClass() != clazz;
} else if (atypes.equals("dalvik.annotation.InnerClass")) {
// access flags of the inner class
int accessFlags = -1;
// name of the inner class
String name = null;
for (AnnotationElem ele : getElements(a.getElements())) {
if (ele instanceof AnnotationIntElem && ele.getName().equals("accessFlags"))
accessFlags = ((AnnotationIntElem) ele).getValue();
else if (ele instanceof AnnotationStringElem && ele.getName().equals("name"))
name = ((AnnotationStringElem) ele).getValue();
else
throw new RuntimeException("Unexpected inner class annotation element");
}
// outer class name
String outerClass;
if (clazz.hasOuterClass()) {
// If we have already set an outer class from some other
// annotation, we use that
// one.
outerClass = clazz.getOuterClass().getName();
} else if (classType.contains("$-")) {
/*
* This is a special case for generated lambda classes of
* jack and jill compiler. Generated lambda classes may
* contain '$' which do not indicate an inner/outer class
* separator if the '$' occurs after a inner class with a
* name starting with '-'. Thus we search for '$-' and
* anything after it including '-' is the inner classes name
* and anything before it is the outer classes name.
*/
outerClass = classType.substring(0, classType.indexOf("$-"));
if (Util.isByteCodeClassName(classType))
outerClass += ";";
} else if (classType.contains("$")) {
// remove everything after the last '$' including the last
// '$'
outerClass = classType.substring(0, classType.lastIndexOf("$")) + ";";
if (Util.isByteCodeClassName(classType))
outerClass += ";";
} else {
// Make sure that no funny business is going on if the
// annotation is broken and does not end in $nn.
outerClass = null;
}
Tag innerTag = new InnerClassTag(DexType.toSootICAT(classType), outerClass == null ? null : DexType.toSootICAT(outerClass), name, accessFlags);
tags.add(innerTag);
if (outerClass != null && !clazz.hasOuterClass()) {
String sootOuterClass = Util.dottedClassName(outerClass);
deps.typesToSignature.add(RefType.v(sootOuterClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(sootOuterClass));
assert clazz.getOuterClass() != clazz;
}
continue;
} else if (atypes.equals("dalvik.annotation.MemberClasses")) {
AnnotationArrayElem e = (AnnotationArrayElem) getElements(a.getElements()).get(0);
for (AnnotationElem ae : e.getValues()) {
AnnotationClassElem c = (AnnotationClassElem) ae;
String innerClass = c.getDesc();
String outerClass;
String name;
if (innerClass.contains("$-")) {
/*
* This is a special case for generated lambda classes
* of jack and jill compiler. Generated lambda classes
* may contain '$' which do not indicate an inner/outer
* class separator if the '$' occurs after a inner class
* with a name starting with '-'. Thus we search for
* '$-' and anything after it including '-' is the inner
* classes name and anything before it is the outer
* classes name.
*/
int i = innerClass.indexOf("$-");
outerClass = innerClass.substring(0, i);
name = innerClass.substring(i + 2).replaceAll(";$", "");
} else if (innerClass.contains("$")) {
// remove everything after the last '$' including the
// last '$'
int i = innerClass.lastIndexOf("$");
outerClass = innerClass.substring(0, i);
name = innerClass.substring(i + 1).replaceAll(";$", "");
} else {
// Make sure that no funny business is going on if the
// annotation is broken and does not end in $nn.
outerClass = null;
name = null;
}
if (// anonymous or
name != null && name.matches("^\\d*$"))
// local inner
// classes
name = null;
// seems like this information is lost
int accessFlags = 0;
// during the .class -- dx --> .dex
// process.
Tag innerTag = new InnerClassTag(DexType.toSootICAT(innerClass), outerClass == null ? null : DexType.toSootICAT(outerClass), name, accessFlags);
tags.add(innerTag);
}
continue;
} else if (atypes.equals("dalvik.annotation.Signature")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation Signature. Got " + eSize + " instead.");
AnnotationArrayElem e = (AnnotationArrayElem) getElements(a.getElements()).get(0);
String sig = "";
for (AnnotationElem ae : e.getValues()) {
AnnotationStringElem s = (AnnotationStringElem) ae;
sig += s.getValue();
}
t = new SignatureTag(sig);
} else if (atypes.equals("dalvik.annotation.Throws")) {
// this is handled in soot.dexpler.DexMethod
continue;
} else if (atypes.equals("java.lang.Deprecated")) {
if (eSize != 0)
throw new RuntimeException("error: expected 1 element for annotation Deprecated. Got " + eSize + " instead.");
t = new DeprecatedTag();
AnnotationTag adt = new AnnotationTag("Ljava/lang/Deprecated;");
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
vatg[v].addAnnotation(adt);
} else {
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
AnnotationTag tag = new AnnotationTag(a.getType());
for (AnnotationElem e : getElements(a.getElements())) tag.addElem(e);
vatg[v].addAnnotation(tag);
}
tags.add(t);
}
for (VisibilityAnnotationTag vat : vatg) if (vat != null)
tags.add(vat);
return tags;
}
use of soot.tagkit.DeprecatedTag in project soot by Sable.
the class Util method resolveFromClassFile.
public void resolveFromClassFile(SootClass aClass, InputStream is, String filePath, Collection<Type> references) {
SootClass bclass = aClass;
String className = bclass.getName();
ClassFile coffiClass = new ClassFile(className);
// Load up class file, and retrieve bclass from class manager.
{
boolean success = coffiClass.loadClassFile(is);
if (!success) {
if (!Scene.v().allowsPhantomRefs())
throw new RuntimeException("Could not load classfile: " + bclass.getName());
else {
logger.warn("" + className + " is a phantom class!");
bclass.setPhantomClass();
return;
}
}
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.this_class];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
name = name.replace('/', '.');
if (!name.equals(bclass.getName())) {
throw new RuntimeException("Error: class " + name + " read in from a classfile in which " + bclass.getName() + " was expected.");
}
}
// Set modifier
bclass.setModifiers(coffiClass.access_flags & (~0x0020));
// don't want the ACC_SUPER flag, it is always supposed to be set
// anyways
// Set superclass
{
if (coffiClass.super_class != 0) {
// This object is not java.lang.Object, so must have a super
// class
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.super_class];
String superName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
superName = superName.replace('/', '.');
references.add(RefType.v(superName));
bclass.setSuperclass(SootResolver.v().makeClassRef(superName));
}
}
// Add interfaces to the bclass
{
for (int i = 0; i < coffiClass.interfaces_count; i++) {
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.interfaces[i]];
String interfaceName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
interfaceName = interfaceName.replace('/', '.');
references.add(RefType.v(interfaceName));
SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceName);
interfaceClass.setModifiers(interfaceClass.getModifiers() | Modifier.INTERFACE);
bclass.addInterface(interfaceClass);
}
}
// Add every field to the bclass
for (int i = 0; i < coffiClass.fields_count; i++) {
field_info fieldInfo = coffiClass.fields[i];
String fieldName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.name_index])).convert();
String fieldDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.descriptor_index])).convert();
int modifiers = fieldInfo.access_flags;
Type fieldType = jimpleTypeOfFieldDescriptor(fieldDescriptor);
SootField field = Scene.v().makeSootField(fieldName, fieldType, modifiers);
bclass.addField(field);
references.add(fieldType);
// add initialization constant, if any
for (int j = 0; j < fieldInfo.attributes_count; j++) {
// add constant value attributes
if (fieldInfo.attributes[j] instanceof ConstantValue_attribute) {
ConstantValue_attribute attr = (ConstantValue_attribute) fieldInfo.attributes[j];
cp_info cval = coffiClass.constant_pool[attr.constantvalue_index];
ConstantValueTag tag;
switch(cval.tag) {
case cp_info.CONSTANT_Integer:
tag = new IntegerConstantValueTag((int) ((CONSTANT_Integer_info) cval).bytes);
break;
case cp_info.CONSTANT_Float:
// tag = new
// FloatConstantValueTag((int)((CONSTANT_Float_info)cval).bytes);
tag = new FloatConstantValueTag(((CONSTANT_Float_info) cval).convert());
break;
case cp_info.CONSTANT_Long:
{
CONSTANT_Long_info lcval = (CONSTANT_Long_info) cval;
tag = new LongConstantValueTag((lcval.high << 32) + lcval.low);
break;
}
case cp_info.CONSTANT_Double:
{
CONSTANT_Double_info dcval = (CONSTANT_Double_info) cval;
// tag = new DoubleConstantValueTag((dcval.high << 32) +
// dcval.low);
tag = new DoubleConstantValueTag(dcval.convert());
break;
}
case cp_info.CONSTANT_String:
{
CONSTANT_String_info scval = (CONSTANT_String_info) cval;
CONSTANT_Utf8_info ucval = (CONSTANT_Utf8_info) coffiClass.constant_pool[scval.string_index];
tag = new StringConstantValueTag(ucval.convert());
break;
}
default:
throw new RuntimeException("unexpected ConstantValue: " + cval);
}
field.addTag(tag);
} else // add synthetic tag
if (fieldInfo.attributes[j] instanceof Synthetic_attribute) {
field.addTag(new SyntheticTag());
} else // add deprecated tag
if (fieldInfo.attributes[j] instanceof Deprecated_attribute) {
field.addTag(new DeprecatedTag());
} else // add signature tag
if (fieldInfo.attributes[j] instanceof Signature_attribute) {
String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) fieldInfo.attributes[j]).signature_index])).convert();
field.addTag(new SignatureTag(generic_sig));
} else if (fieldInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || fieldInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
addAnnotationVisibilityAttribute(field, fieldInfo.attributes[j], coffiClass, references);
} else if (fieldInfo.attributes[j] instanceof Generic_attribute) {
Generic_attribute attr = (Generic_attribute) fieldInfo.attributes[j];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
field.addTag(new GenericAttribute(name, attr.info));
}
}
}
// Add every method to the bclass
for (int i = 0; i < coffiClass.methods_count; i++) {
method_info methodInfo = coffiClass.methods[i];
if ((coffiClass.constant_pool[methodInfo.name_index]) == null) {
logger.debug("method index: " + methodInfo.toName(coffiClass.constant_pool));
throw new RuntimeException("method has no name");
}
String methodName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.name_index])).convert();
String methodDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.descriptor_index])).convert();
List<Type> parameterTypes;
Type returnType;
// Generate parameterTypes & returnType
{
Type[] types = jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor);
parameterTypes = new ArrayList<Type>();
for (int j = 0; j < types.length - 1; j++) {
references.add(types[j]);
parameterTypes.add(types[j]);
}
returnType = types[types.length - 1];
references.add(returnType);
}
int modifiers = methodInfo.access_flags;
SootMethod method;
method = Scene.v().makeSootMethod(methodName, parameterTypes, returnType, modifiers);
bclass.addMethod(method);
methodInfo.jmethod = method;
// add exceptions to method
{
for (int j = 0; j < methodInfo.attributes_count; j++) {
if (methodInfo.attributes[j] instanceof Exception_attribute) {
Exception_attribute exceptions = (Exception_attribute) methodInfo.attributes[j];
for (int k = 0; k < exceptions.number_of_exceptions; k++) {
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[exceptions.exception_index_table[k]];
String exceptionName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
exceptionName = exceptionName.replace('/', '.');
references.add(RefType.v(exceptionName));
method.addExceptionIfAbsent(SootResolver.v().makeClassRef(exceptionName));
}
} else if (methodInfo.attributes[j] instanceof Synthetic_attribute) {
method.addTag(new SyntheticTag());
} else if (methodInfo.attributes[j] instanceof Deprecated_attribute) {
method.addTag(new DeprecatedTag());
} else if (methodInfo.attributes[j] instanceof Signature_attribute) {
String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) methodInfo.attributes[j]).signature_index])).convert();
method.addTag(new SignatureTag(generic_sig));
} else if (methodInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
addAnnotationVisibilityAttribute(method, methodInfo.attributes[j], coffiClass, references);
} else if (methodInfo.attributes[j] instanceof RuntimeVisibleParameterAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleParameterAnnotations_attribute) {
addAnnotationVisibilityParameterAttribute(method, methodInfo.attributes[j], coffiClass, references);
} else if (methodInfo.attributes[j] instanceof AnnotationDefault_attribute) {
AnnotationDefault_attribute attr = (AnnotationDefault_attribute) methodInfo.attributes[j];
element_value[] input = new element_value[1];
input[0] = attr.default_value;
ArrayList<AnnotationElem> list = createElementTags(1, coffiClass, input);
method.addTag(new AnnotationDefaultTag(list.get(0)));
} else if (methodInfo.attributes[j] instanceof Generic_attribute) {
Generic_attribute attr = (Generic_attribute) methodInfo.attributes[j];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
method.addTag(new GenericAttribute(name, attr.info));
}
}
}
// Go through the constant pool, forcing all mentioned classes to be
// resolved.
{
for (int k = 0; k < coffiClass.constant_pool_count; k++) {
if (coffiClass.constant_pool[k] instanceof CONSTANT_Class_info) {
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[k];
String desc = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
String name = desc.replace('/', '.');
if (name.startsWith("["))
references.add(jimpleTypeOfFieldDescriptor(desc));
else
references.add(RefType.v(name));
}
if (coffiClass.constant_pool[k] instanceof CONSTANT_Fieldref_info || coffiClass.constant_pool[k] instanceof CONSTANT_Methodref_info || coffiClass.constant_pool[k] instanceof CONSTANT_InterfaceMethodref_info) {
Type[] types = jimpleTypesOfFieldOrMethodDescriptor(cp_info.getTypeDescr(coffiClass.constant_pool, k));
for (Type element : types) {
references.add(element);
}
}
}
}
}
// Set coffi source of method
for (int i = 0; i < coffiClass.methods_count; i++) {
method_info methodInfo = coffiClass.methods[i];
// methodInfo.jmethod.setSource(coffiClass, methodInfo);
methodInfo.jmethod.setSource(new CoffiMethodSource(coffiClass, methodInfo));
}
// Set "SourceFile" attribute tag
for (int i = 0; i < coffiClass.attributes_count; i++) {
if (coffiClass.attributes[i] instanceof SourceFile_attribute) {
SourceFile_attribute attr = (SourceFile_attribute) coffiClass.attributes[i];
String sourceFile = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.sourcefile_index])).convert();
if (sourceFile.indexOf(' ') >= 0) {
logger.debug("" + "Warning: Class " + className + " has invalid SourceFile attribute (will be ignored).");
} else {
bclass.addTag(new SourceFileTag(sourceFile, filePath));
}
} else // Set "InnerClass" attribute tag
if (coffiClass.attributes[i] instanceof InnerClasses_attribute) {
InnerClasses_attribute attr = (InnerClasses_attribute) coffiClass.attributes[i];
for (int j = 0; j < attr.inner_classes_length; j++) {
inner_class_entry e = attr.inner_classes[j];
String inner = null;
String outer = null;
String name = null;
if (e.inner_class_index != 0)
inner = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[e.inner_class_index]).name_index]).convert();
if (e.outer_class_index != 0)
outer = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[e.outer_class_index]).name_index]).convert();
if (e.name_index != 0)
name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[e.name_index])).convert();
bclass.addTag(new InnerClassTag(inner, outer, name, e.access_flags));
}
} else // set synthetic tags
if (coffiClass.attributes[i] instanceof Synthetic_attribute) {
bclass.addTag(new SyntheticTag());
} else // set deprectaed tags
if (coffiClass.attributes[i] instanceof Deprecated_attribute) {
bclass.addTag(new DeprecatedTag());
} else if (coffiClass.attributes[i] instanceof Signature_attribute) {
String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) coffiClass.attributes[i]).signature_index])).convert();
bclass.addTag(new SignatureTag(generic_sig));
} else if (coffiClass.attributes[i] instanceof EnclosingMethod_attribute) {
EnclosingMethod_attribute attr = (EnclosingMethod_attribute) coffiClass.attributes[i];
String class_name = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[attr.class_index]).name_index]).convert();
CONSTANT_NameAndType_info info = (CONSTANT_NameAndType_info) coffiClass.constant_pool[attr.method_index];
String method_name = "";
String method_sig = "";
if (info != null) {
method_name = ((CONSTANT_Utf8_info) coffiClass.constant_pool[info.name_index]).convert();
method_sig = ((CONSTANT_Utf8_info) coffiClass.constant_pool[info.descriptor_index]).convert();
}
bclass.addTag(new EnclosingMethodTag(class_name, method_name, method_sig));
} else if (coffiClass.attributes[i] instanceof RuntimeVisibleAnnotations_attribute || coffiClass.attributes[i] instanceof RuntimeInvisibleAnnotations_attribute) {
addAnnotationVisibilityAttribute(bclass, coffiClass.attributes[i], coffiClass, references);
} else if (coffiClass.attributes[i] instanceof Generic_attribute) {
Generic_attribute attr = (Generic_attribute) coffiClass.attributes[i];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
bclass.addTag(new GenericAttribute(name, attr.info));
}
}
}
use of soot.tagkit.DeprecatedTag in project soot by Sable.
the class DexAnnotation method handleMethodAnnotation.
/**
* Converts method and method parameters annotations from Dexlib to Jimple
*
* @param h
* @param method
*/
public void handleMethodAnnotation(Host h, Method method) {
Set<? extends Annotation> aSet = method.getAnnotations();
if (!(aSet == null || aSet.isEmpty())) {
List<Tag> tags = handleAnnotation(aSet, null);
if (tags != null)
for (Tag t : tags) if (t != null) {
h.addTag(t);
}
}
String[] parameterNames = null;
int i = 0;
for (MethodParameter p : method.getParameters()) {
String name = p.getName();
if (name != null) {
parameterNames = new String[method.getParameters().size()];
parameterNames[i] = name;
}
i++;
}
if (parameterNames != null) {
h.addTag(new ParamNamesTag(parameterNames));
}
// Is there any parameter annotation?
boolean doParam = false;
List<? extends MethodParameter> parameters = method.getParameters();
for (MethodParameter p : parameters) {
if (p.getAnnotations().size() > 0) {
doParam = true;
break;
}
}
if (doParam) {
VisibilityParameterAnnotationTag tag = new VisibilityParameterAnnotationTag(parameters.size(), AnnotationConstants.RUNTIME_VISIBLE);
for (MethodParameter p : parameters) {
List<Tag> tags = handleAnnotation(p.getAnnotations(), null);
// so that we keep the order intact.
if (tags == null) {
tag.addVisibilityAnnotation(null);
continue;
}
VisibilityAnnotationTag paramVat = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_VISIBLE);
tag.addVisibilityAnnotation(paramVat);
for (Tag t : tags) {
if (t == null)
continue;
AnnotationTag vat = null;
if (!(t instanceof VisibilityAnnotationTag)) {
if (t instanceof DeprecatedTag) {
vat = new AnnotationTag("Ljava/lang/Deprecated;");
} else if (t instanceof SignatureTag) {
SignatureTag sig = (SignatureTag) t;
ArrayList<AnnotationElem> sigElements = new ArrayList<AnnotationElem>();
for (String s : SootToDexUtils.splitSignature(sig.getSignature())) sigElements.add(new AnnotationStringElem(s, 's', "value"));
AnnotationElem elem = new AnnotationArrayElem(sigElements, '[', "value");
vat = new AnnotationTag("Ldalvik/annotation/Signature;", Collections.singleton(elem));
} else {
throw new RuntimeException("error: unhandled tag for parameter annotation in method " + h + " (" + t + ").");
}
} else {
vat = ((VisibilityAnnotationTag) t).getAnnotations().get(0);
}
paramVat.addAnnotation(vat);
}
}
if (tag.getVisibilityAnnotations().size() > 0)
h.addTag(tag);
}
}
Aggregations