use of soot.tagkit.InnerClassTag 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.InnerClassTag in project soot by Sable.
the class SootClassBuilder method visitInnerClass.
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
klass.addTag(new InnerClassTag(name, outerName, innerName, access));
// soot does not resolve all inner classes, e.g., java.util.stream.FindOps$FindSink$... is not resolved
String innerClassname = AsmUtil.toQualifiedName(name);
deps.add(RefType.v(innerClassname));
}
use of soot.tagkit.InnerClassTag 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.InnerClassTag in project soot by Sable.
the class DexPrinter method buildInnerClassAttribute.
private List<Annotation> buildInnerClassAttribute(SootClass parentClass, InnerClassAttribute t, Set<String> skipList) {
if (t.getSpecs() == null)
return null;
List<Annotation> anns = null;
for (Tag t2 : t.getSpecs()) {
InnerClassTag icTag = (InnerClassTag) t2;
// In Dalvik, both the EnclosingMethod/EnclosingClass tag and the
// InnerClass tag are written to the inner class which is different
// to Java. We thus check whether this tag actually points to our
// outer class.
String outerClass = DexInnerClassParser.getOuterClassNameFromTag(icTag);
String innerClass = icTag.getInnerClass().replaceAll("/", ".");
// next tag.
if (!parentClass.hasOuterClass() || !innerClass.equals(parentClass.getName()))
continue;
// If the outer class points to the very same class, we null it
if (parentClass.getName().equals(outerClass) && icTag.getOuterClass() == null)
outerClass = null;
// Do not write garbage. Never.
if (parentClass.getName().equals(outerClass))
continue;
// This is an actual inner class. Write the annotation
if (skipList.add("Ldalvik/annotation/InnerClass;")) {
// InnerClass annotation
List<AnnotationElement> elements = new ArrayList<AnnotationElement>();
ImmutableAnnotationElement flagsElement = new ImmutableAnnotationElement("accessFlags", new ImmutableIntEncodedValue(icTag.getAccessFlags()));
elements.add(flagsElement);
ImmutableEncodedValue nameValue;
if (icTag.getShortName() != null && !icTag.getShortName().isEmpty())
nameValue = new ImmutableStringEncodedValue(icTag.getShortName());
else
nameValue = ImmutableNullEncodedValue.INSTANCE;
ImmutableAnnotationElement nameElement = new ImmutableAnnotationElement("name", nameValue);
elements.add(nameElement);
if (anns == null)
anns = new ArrayList<Annotation>();
anns.add(new ImmutableAnnotation(AnnotationVisibility.SYSTEM, "Ldalvik/annotation/InnerClass;", elements));
}
}
return anns;
}
use of soot.tagkit.InnerClassTag in project soot by Sable.
the class DexPrinter method buildMemberClassesAttribute.
private List<Annotation> buildMemberClassesAttribute(SootClass parentClass, InnerClassAttribute t, Set<String> skipList) {
List<Annotation> anns = null;
Set<String> memberClasses = null;
// Collect the inner classes
for (Tag t2 : t.getSpecs()) {
InnerClassTag icTag = (InnerClassTag) t2;
String outerClass = DexInnerClassParser.getOuterClassNameFromTag(icTag);
// Only classes with names are member classes
if (icTag.getOuterClass() != null && parentClass.getName().equals(outerClass)) {
if (memberClasses == null)
memberClasses = new HashSet<String>();
memberClasses.add(SootToDexUtils.getDexClassName(icTag.getInnerClass()));
}
}
// Write the member classes
if (memberClasses != null && !memberClasses.isEmpty() && skipList.add("Ldalvik/annotation/MemberClasses;")) {
List<EncodedValue> classes = new ArrayList<EncodedValue>();
for (String memberClass : memberClasses) {
ImmutableTypeEncodedValue classValue = new ImmutableTypeEncodedValue(memberClass);
classes.add(classValue);
}
ImmutableArrayEncodedValue classesValue = new ImmutableArrayEncodedValue(classes);
ImmutableAnnotationElement element = new ImmutableAnnotationElement("value", classesValue);
ImmutableAnnotation memberAnnotation = new ImmutableAnnotation(AnnotationVisibility.SYSTEM, "Ldalvik/annotation/MemberClasses;", Collections.singletonList(element));
if (anns == null)
anns = new ArrayList<Annotation>();
anns.add(memberAnnotation);
}
return anns;
}
Aggregations