use of soot.tagkit.AnnotationAnnotationElem in project soot by Sable.
the class DexPrinter method buildClassAnnotations.
private Set<Annotation> buildClassAnnotations(SootClass c) {
Set<String> skipList = new HashSet<String>();
Set<Annotation> annotations = buildCommonAnnotations(c, skipList);
// so we test for enclosing methods first.
if (c.hasTag("EnclosingMethodTag")) {
EnclosingMethodTag eMethTag = (EnclosingMethodTag) c.getTag("EnclosingMethodTag");
Annotation enclosingMethodItem = buildEnclosingMethodTag(eMethTag, skipList);
if (enclosingMethodItem != null)
annotations.add(enclosingMethodItem);
} else if (c.hasOuterClass()) {
if (skipList.add("Ldalvik/annotation/EnclosingClass;")) {
// EnclosingClass annotation
ImmutableAnnotationElement enclosingElement = new ImmutableAnnotationElement("value", new ImmutableTypeEncodedValue(SootToDexUtils.getDexClassName(c.getOuterClass().getName())));
annotations.add(new ImmutableAnnotation(AnnotationVisibility.SYSTEM, "Ldalvik/annotation/EnclosingClass;", Collections.singleton(enclosingElement)));
}
}
// respective inner classes.
if (c.hasOuterClass()) {
InnerClassAttribute icTag = (InnerClassAttribute) c.getOuterClass().getTag("InnerClassAttribute");
if (icTag != null) {
List<Annotation> innerClassItem = buildInnerClassAttribute(c, icTag, skipList);
if (innerClassItem != null)
annotations.addAll(innerClassItem);
}
}
// Write the MemberClasses tag
InnerClassAttribute icTag = (InnerClassAttribute) c.getTag("InnerClassAttribute");
if (icTag != null) {
List<Annotation> memberClassesItem = buildMemberClassesAttribute(c, icTag, skipList);
if (memberClassesItem != null)
annotations.addAll(memberClassesItem);
}
for (Tag t : c.getTags()) {
if (t.getName().equals("VisibilityAnnotationTag")) {
List<ImmutableAnnotation> visibilityItems = buildVisibilityAnnotationTag((VisibilityAnnotationTag) t, skipList);
annotations.addAll(visibilityItems);
}
}
// Write default-annotation tags
List<AnnotationElem> defaults = new ArrayList<AnnotationElem>();
for (SootMethod method : c.getMethods()) {
AnnotationDefaultTag tag = (AnnotationDefaultTag) method.getTag("AnnotationDefaultTag");
if (tag != null) {
tag.getDefaultVal().setName(method.getName());
defaults.add(tag.getDefaultVal());
}
}
if (defaults.size() > 0) {
VisibilityAnnotationTag defaultAnnotationTag = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_INVISIBLE);
AnnotationTag a = new AnnotationTag("Ldalvik/annotation/AnnotationDefault;");
defaultAnnotationTag.addAnnotation(a);
AnnotationTag at = new AnnotationTag(SootToDexUtils.getDexClassName(c.getName()));
AnnotationAnnotationElem ae = new AnnotationAnnotationElem(at, '@', "value");
a.addElem(ae);
for (AnnotationElem aelem : defaults) at.addElem(aelem);
List<ImmutableAnnotation> visibilityItems = buildVisibilityAnnotationTag(defaultAnnotationTag, skipList);
annotations.addAll(visibilityItems);
}
return annotations;
}
use of soot.tagkit.AnnotationAnnotationElem in project soot by Sable.
the class DexAnnotation method handleAnnotationElement.
private ArrayList<AnnotationElem> handleAnnotationElement(AnnotationElement ae, List<? extends EncodedValue> evList) {
ArrayList<AnnotationElem> aelemList = new ArrayList<AnnotationElem>();
for (EncodedValue ev : evList) {
int type = ev.getValueType();
AnnotationElem elem = null;
switch(type) {
case // BYTE
0x00:
{
ByteEncodedValue v = (ByteEncodedValue) ev;
elem = new AnnotationIntElem(v.getValue(), 'B', ae.getName());
break;
}
case // SHORT
0x02:
{
ShortEncodedValue v = (ShortEncodedValue) ev;
elem = new AnnotationIntElem(v.getValue(), 'S', ae.getName());
break;
}
case // CHAR
0x03:
{
CharEncodedValue v = (CharEncodedValue) ev;
elem = new AnnotationIntElem(v.getValue(), 'C', ae.getName());
break;
}
case // INT
0x04:
{
IntEncodedValue v = (IntEncodedValue) ev;
elem = new AnnotationIntElem(v.getValue(), 'I', ae.getName());
break;
}
case // LONG
0x06:
{
LongEncodedValue v = (LongEncodedValue) ev;
elem = new AnnotationLongElem(v.getValue(), 'J', ae.getName());
break;
}
case // FLOAT
0x10:
{
FloatEncodedValue v = (FloatEncodedValue) ev;
elem = new AnnotationFloatElem(v.getValue(), 'F', ae.getName());
break;
}
case // DOUBLE
0x11:
{
DoubleEncodedValue v = (DoubleEncodedValue) ev;
elem = new AnnotationDoubleElem(v.getValue(), 'D', ae.getName());
break;
}
case // STRING
0x17:
{
StringEncodedValue v = (StringEncodedValue) ev;
elem = new AnnotationStringElem(v.getValue(), 's', ae.getName());
break;
}
case // TYPE
0x18:
{
TypeEncodedValue v = (TypeEncodedValue) ev;
elem = new AnnotationClassElem(v.getValue(), 'c', ae.getName());
break;
}
case // FIELD (Dalvik specific?)
0x19:
{
FieldEncodedValue v = (FieldEncodedValue) ev;
FieldReference fr = v.getValue();
String fieldSig = "";
fieldSig += DexType.toSootAT(fr.getDefiningClass()) + ": ";
fieldSig += DexType.toSootAT(fr.getType()) + " ";
fieldSig += fr.getName();
elem = new AnnotationStringElem(fieldSig, 'f', ae.getName());
break;
}
case // METHOD (Dalvik specific?)
0x1a:
{
MethodEncodedValue v = (MethodEncodedValue) ev;
MethodReference mr = v.getValue();
String className = DexType.toSootICAT(mr.getDefiningClass());
String returnType = DexType.toSootAT(mr.getReturnType());
String methodName = mr.getName();
String parameters = "";
for (CharSequence p : mr.getParameterTypes()) {
parameters += DexType.toSootAT(p.toString());
}
String mSig = className + " |" + methodName + " |" + parameters + " |" + returnType;
elem = new AnnotationStringElem(mSig, 'M', ae.getName());
break;
}
case // ENUM : Warning -> encoding Dalvik specific!
0x1b:
{
EnumEncodedValue v = (EnumEncodedValue) ev;
FieldReference fr = v.getValue();
elem = new AnnotationEnumElem(DexType.toSootAT(fr.getType()).toString(), fr.getName(), 'e', ae.getName());
break;
}
case // ARRAY
0x1c:
{
ArrayEncodedValue v = (ArrayEncodedValue) ev;
ArrayList<AnnotationElem> l = handleAnnotationElement(ae, v.getValue());
if (l != null)
elem = new AnnotationArrayElem(l, '[', ae.getName());
break;
}
case // ANNOTATION
0x1d:
{
AnnotationEncodedValue v = (AnnotationEncodedValue) ev;
AnnotationTag t = new AnnotationTag(DexType.toSootAT(v.getType()).toString());
for (AnnotationElement newElem : v.getElements()) {
List<EncodedValue> l = new ArrayList<EncodedValue>();
l.add(newElem.getValue());
List<AnnotationElem> aList = handleAnnotationElement(newElem, l);
if (aList != null)
for (AnnotationElem e : aList) t.addElem(e);
}
elem = new AnnotationAnnotationElem(t, '@', ae.getName());
break;
}
case // NULL (Dalvik specific?)
0x1e:
{
elem = new AnnotationStringElem(null, 'N', ae.getName());
break;
}
case // BOOLEAN
0x1f:
{
BooleanEncodedValue v = (BooleanEncodedValue) ev;
elem = new AnnotationBooleanElem(v.getValue(), 'Z', ae.getName());
break;
}
default:
{
throw new RuntimeException("Unknown annotation element 0x" + Integer.toHexString(type));
}
}
if (elem != null)
aelemList.add(elem);
}
return aelemList;
}
use of soot.tagkit.AnnotationAnnotationElem in project soot by Sable.
the class DexAnnotation method handleClassAnnotation.
/**
* Converts Class annotations from Dexlib to Jimple.
*
* @param h
* @param classDef
*/
// .annotation "Ldalvik/annotation/AnnotationDefault;"
// .annotation "Ldalvik/annotation/EnclosingClass;"
// .annotation "Ldalvik/annotation/EnclosingMethod;"
// .annotation "Ldalvik/annotation/InnerClass;"
// .annotation "Ldalvik/annotation/MemberClasses;"
// .annotation "Ldalvik/annotation/Signature;"
// .annotation "Ldalvik/annotation/Throws;"
public void handleClassAnnotation(ClassDef classDef) {
Set<? extends Annotation> aSet = classDef.getAnnotations();
if (aSet == null || aSet.isEmpty())
return;
List<Tag> tags = handleAnnotation(aSet, classDef.getType());
if (tags == null)
return;
InnerClassAttribute ica = null;
for (Tag t : tags) if (t != null) {
if (t instanceof InnerClassTag) {
if (ica == null) {
// Do we already have an InnerClassAttribute?
ica = (InnerClassAttribute) clazz.getTag("InnerClassAttribute");
// If not, create one
if (ica == null) {
ica = new InnerClassAttribute();
clazz.addTag(ica);
}
}
ica.add((InnerClassTag) t);
} else if (t instanceof VisibilityAnnotationTag) {
// If a dalvik/annotation/AnnotationDefault tag is present
// in a class, its AnnotationElements must be propagated
// to methods through the creation of new
// AnnotationDefaultTag.
VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t;
for (AnnotationTag a : vt.getAnnotations()) {
if (a.getType().equals("Ldalvik/annotation/AnnotationDefault;")) {
for (AnnotationElem ae : a.getElems()) {
if (ae instanceof AnnotationAnnotationElem) {
AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae;
AnnotationTag at = aae.getValue();
// extract default elements
Map<String, AnnotationElem> defaults = new HashMap<String, AnnotationElem>();
for (AnnotationElem aelem : at.getElems()) {
defaults.put(aelem.getName(), aelem);
}
// and add tags on methods
for (SootMethod sm : clazz.getMethods()) {
String methodName = sm.getName();
if (defaults.containsKey(methodName)) {
AnnotationElem e = defaults.get(methodName);
// Okay, the name is the same, but
// is it actually the same type?
Type annotationType = getSootType(e);
boolean isCorrectType = false;
if (annotationType == null) {
// we do not know the type of
// the annotation, so we guess
// it's the correct type.
isCorrectType = true;
} else {
if (annotationType.equals(sm.getReturnType())) {
isCorrectType = true;
} else if (annotationType.equals(ARRAY_TYPE)) {
if (sm.getReturnType() instanceof ArrayType)
isCorrectType = true;
}
}
if (isCorrectType && sm.getParameterCount() == 0) {
e.setName("default");
AnnotationDefaultTag d = new AnnotationDefaultTag(e);
sm.addTag(d);
// In case there is more than
// one matching method, we only
// use the first one
defaults.remove(sm.getName());
}
}
}
for (Entry<String, AnnotationElem> leftOverEntry : defaults.entrySet()) {
// We were not able to find a matching
// method for the tag, because the
// return signature
// does not match
SootMethod found = clazz.getMethodByNameUnsafe(leftOverEntry.getKey());
AnnotationElem element = leftOverEntry.getValue();
if (found != null) {
element.setName("default");
AnnotationDefaultTag d = new AnnotationDefaultTag(element);
found.addTag(d);
}
}
}
}
}
}
if (!(vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE))
clazz.addTag(vt);
} else {
clazz.addTag(t);
}
}
}
Aggregations