use of soot.tagkit.InnerClassAttribute 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.InnerClassAttribute in project soot by Sable.
the class AbstractASMBackend method generateInnerClassReferences.
/**
* Emits the bytecode for all references to inner classes if present
*/
protected void generateInnerClassReferences() {
if (sc.hasTag("InnerClassAttribute") && !Options.v().no_output_inner_classes_attribute()) {
InnerClassAttribute ica = (InnerClassAttribute) sc.getTag("InnerClassAttribute");
List<InnerClassTag> sortedTags = new ArrayList<InnerClassTag>(ica.getSpecs());
Collections.sort(sortedTags, new SootInnerClassComparator());
for (InnerClassTag ict : sortedTags) {
String name = slashify(ict.getInnerClass());
String outerClassName = slashify(ict.getOuterClass());
String innerName = slashify(ict.getShortName());
int access = ict.getAccessFlags();
cv.visitInnerClass(name, outerClassName, innerName, access);
}
}
}
use of soot.tagkit.InnerClassAttribute 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);
}
}
}
use of soot.tagkit.InnerClassAttribute in project soot by Sable.
the class DexClassLoader method makeSootClass.
public Dependencies makeSootClass(SootClass sc, ClassDef defItem, DexFile dexFile) {
String superClass = defItem.getSuperclass();
Dependencies deps = new Dependencies();
// source file
String sourceFile = defItem.getSourceFile();
if (sourceFile != null) {
sc.addTag(new SourceFileTag(sourceFile));
}
// super class for hierarchy level
if (superClass != null) {
String superClassName = Util.dottedClassName(superClass);
SootClass sootSuperClass = SootResolver.v().makeClassRef(superClassName);
sc.setSuperclass(sootSuperClass);
deps.typesToHierarchy.add(sootSuperClass.getType());
}
// access flags
int accessFlags = defItem.getAccessFlags();
sc.setModifiers(accessFlags);
// Retrieve interface names
if (defItem.getInterfaces() != null) {
for (String interfaceName : defItem.getInterfaces()) {
String interfaceClassName = Util.dottedClassName(interfaceName);
if (sc.implementsInterface(interfaceClassName))
continue;
SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceClassName);
interfaceClass.setModifiers(interfaceClass.getModifiers() | Modifier.INTERFACE);
sc.addInterface(interfaceClass);
deps.typesToHierarchy.add(interfaceClass.getType());
}
}
if (Options.v().oaat() && sc.resolvingLevel() <= SootClass.HIERARCHY) {
return deps;
}
DexAnnotation da = new DexAnnotation(sc, deps);
// get the fields of the class
for (Field sf : defItem.getStaticFields()) {
loadField(sc, da, sf);
}
for (Field f : defItem.getInstanceFields()) {
loadField(sc, da, f);
}
// get the methods of the class
DexMethod dexMethod = createDexMethodFactory(dexFile, sc);
for (Method method : defItem.getDirectMethods()) {
loadMethod(method, sc, da, dexMethod);
}
for (Method method : defItem.getVirtualMethods()) {
loadMethod(method, sc, da, dexMethod);
}
da.handleClassAnnotation(defItem);
// In contrast to Java, Dalvik associates the InnerClassAttribute
// with the inner class, not the outer one. We need to copy the
// tags over to correspond to the Soot semantics.
InnerClassAttribute ica = (InnerClassAttribute) sc.getTag("InnerClassAttribute");
if (ica != null) {
Iterator<InnerClassTag> innerTagIt = ica.getSpecs().iterator();
while (innerTagIt.hasNext()) {
Tag t = innerTagIt.next();
if (t instanceof InnerClassTag) {
InnerClassTag ict = (InnerClassTag) t;
// Get the outer class name
String outer = DexInnerClassParser.getOuterClassNameFromTag(ict);
if (outer == null) {
// If we don't have any clue what the outer class is, we
// just remove
// the reference entirely
innerTagIt.remove();
continue;
}
// we leave it as it is
if (outer.equals(sc.getName()))
continue;
// Check the inner class to make sure that this tag actually
// refers to the current class as the inner class
String inner = ict.getInnerClass().replaceAll("/", ".");
if (!inner.equals(sc.getName())) {
innerTagIt.remove();
continue;
}
SootClass osc = SootResolver.v().makeClassRef(outer);
if (osc == sc) {
if (!sc.hasOuterClass())
continue;
osc = sc.getOuterClass();
} else
deps.typesToHierarchy.add(osc.getType());
// Get the InnerClassAttribute of the outer class
InnerClassAttribute icat = (InnerClassAttribute) osc.getTag("InnerClassAttribute");
if (icat == null) {
icat = new InnerClassAttribute();
osc.addTag(icat);
}
// Transfer the tag from the inner class to the outer class
InnerClassTag newt = new InnerClassTag(ict.getInnerClass(), ict.getOuterClass(), ict.getShortName(), ict.getAccessFlags());
icat.add(newt);
// Remove the tag from the inner class as inner classes do
// not have these tags in the Java / Soot semantics. The
// DexPrinter will copy it back if we do dex->dex.
innerTagIt.remove();
// within the PackManager in method handleInnerClasses().
if (!sc.hasTag("InnerClassTag")) {
if (((InnerClassTag) t).getInnerClass().replaceAll("/", ".").equals(sc.toString())) {
sc.addTag(t);
}
}
}
}
// remove tag if empty
if (ica.getSpecs().isEmpty()) {
sc.getTags().remove(ica);
}
}
return deps;
}
Aggregations