use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.
the class ClinitOrder method findDependencies.
private Set<ClassInfo> findDependencies(MethodInfo method, boolean inRec) {
// System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
Set<ClassInfo> depends = new HashSet<ClassInfo>();
if (method.isNative() || method.isAbstract()) {
// subclasses???? :-(
return depends;
}
ClassInfo classInfo = method.getClassInfo();
ConstantPoolGen cpoolgen = method.getConstantPoolGen();
InstructionList il = method.getCode().getInstructionList();
InstructionFinder f = new InstructionFinder(il);
// TODO can we encounter an empty instruction list?
//if(il.getStart() == null) {
// return depends;
//}
// find instructions that access the constant pool
// collect all indices to constants in ClassInfo
String cpInstr = "CPInstruction";
for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) it.next();
InstructionHandle first = match[0];
CPInstruction ii = (CPInstruction) first.getInstruction();
int idx = ii.getIndex();
Constant co = cpoolgen.getConstant(idx);
ClassRef classRef = null;
Set addDepends = null;
ClassInfo clinfo;
MethodInfo minfo;
switch(co.getTag()) {
case Constants.CONSTANT_Class:
classRef = classInfo.getConstantInfo(co).getClassRef();
clinfo = classRef.getClassInfo();
if (clinfo != null) {
minfo = clinfo.getMethodInfo("<init>()V");
if (minfo != null) {
addDepends = findDependencies(minfo, true);
}
}
break;
case Constants.CONSTANT_Fieldref:
case Constants.CONSTANT_InterfaceMethodref:
classRef = classInfo.getConstantInfo(co).getClassRef();
break;
case Constants.CONSTANT_Methodref:
ConstantMethodInfo mref = (ConstantMethodInfo) classInfo.getConstantInfo(co);
classRef = mref.getClassRef();
minfo = mref.getMethodRef().getMethodInfo();
if (minfo != null) {
addDepends = findDependencies(minfo, true);
}
break;
}
if (classRef != null) {
ClassInfo clinf = classRef.getClassInfo();
if (clinf != null) {
if (clinf.getMethodInfo(clinitSig) != null) {
// don't add myself as dependency
if (!clinf.equals(method.getClassInfo())) {
depends.add(clinf);
}
}
}
}
if (addDepends != null) {
for (Object addDepend : addDepends) {
ClassInfo addCli = (ClassInfo) addDepend;
if (addCli.equals(method.getClassInfo())) {
throw new JavaClassFormatError("cyclic indirect <clinit> dependency");
}
depends.add(addCli);
}
}
}
return depends;
}
use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.
the class AppInfo method getMethodRef.
/**
* Get a reference to a method using the given memberID.
* If the method is defined only in a (known) superclass and is inherited by this class,
* get a methodRef which contains a ClassRef to the given class but a MethodInfo from the superclass.
* <p>
* If you already have a classRef, use {@link #getMethodRef(ClassRef, MemberID)}
* instead.
* </p>
* @param memberID the memberID of the method
* @param isInterfaceMethod true if the class is an interface.
* @return a method reference with or without MethodInfo or ClassInfo.
*/
public MethodRef getMethodRef(MemberID memberID, boolean isInterfaceMethod) {
ClassInfo cls = classes.get(memberID.getClassName());
ClassRef clsRef;
if (cls != null) {
if (cls.isInterface() != isInterfaceMethod) {
throw new ClassFormatException("Class '" + cls.getClassName() + "' interface flag does not match.");
}
clsRef = cls.getClassRef();
} else {
clsRef = new ClassRef(memberID.getClassName(), isInterfaceMethod);
}
return getMethodRef(clsRef, memberID);
}
use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.
the class AppInfo method getFieldRef.
public FieldRef getFieldRef(String className, String fieldName) {
ClassInfo cls = classes.get(className);
ClassRef clsRef;
if (cls != null) {
FieldInfo field = cls.getFieldInfo(fieldName);
if (field != null) {
return field.getFieldRef();
}
clsRef = cls.getClassRef();
} else {
clsRef = new ClassRef(className);
}
return new FieldRef(clsRef, fieldName, null);
}
use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.
the class AppInfo method getMethodRef.
public MethodRef getMethodRef(MemberID memberID) {
ClassInfo cls = classes.get(memberID.getClassName());
ClassRef clsRef;
if (cls != null) {
clsRef = cls.getClassRef();
} else {
clsRef = new ClassRef(memberID.getClassName());
}
return getMethodRef(clsRef, memberID);
}
use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.
the class InnerClassesInfo method buildInnerClassesAttribute.
/*
* Make this class a member nested class of the given class or move it to top-level
*
* @param enclosingClass the new outer class of this class, or null to make it a toplevel class.
* @param innerName the simple name of this member class.
*/
/*
public void setEnclosingClass(ClassInfo enclosingClass, String innerName) throws AppInfoException {
// implement setOuterClass(), if needed. But this is not a simple task.
// need to
// - remove references to old outerClass from InnerClasses of this and all old outer classes
// - create InnerClasses attribute if none exists
// - add new entries to InnerClasses of this and all new outer classes.
// - update class hierarchy infos and fullyKnown flags
// - handle setEnclosingClass(null)
}
*/
/*
* Make this class a local nested class of the given method.
* @param methodInfo the enclosing method of this class.
*/
/*
public void setEnclosingMethod(MethodInfo methodInfo) {
}
*/
/*
* Add or replace InnerClass entries of this class with the info of the given classes.
* If no InnerClasses attribute exists, it is created. Enclosing classes are added if needed.
*
* @param nestedClasses a list of nested classes to add to the InnerClasses attribute.
*/
/*
public void addInnerClassRefs(Collection<ClassRef> nestedClasses) {
if ( nestedClasses == null || nestedClasses.isEmpty() ) {
return;
}
Map<String, InnerClass> classes = buildInnerClasses(nestedClasses);
// create an InnerClasses attribute if it does not exist
// add all InnerClasses to the existing InnerClasses (replace entries if existing)
}
*/
/**
* Build a new InnerClasses Attribute containing entries for all inner classes referenced by the current
* constantpool, using the current ClassInfos or the old InnerClasses attribute to build the table.
*
* @return a new InnerClasses attribute or null if this class does not reference any inner classes.
*/
public InnerClasses buildInnerClassesAttribute() {
ConstantPoolGen cpg = classGen.getConstantPool();
// check+update InnerClasses attribute (and add referenced nested classes)
List<ClassRef> referencedClasses = new LinkedList<ClassRef>();
for (String name : ConstantPoolReferenceFinder.findReferencedClasses(classInfo)) {
referencedClasses.add(classInfo.getAppInfo().getClassRef(name));
}
// find all referenced classes recursively, build InnerClass list from ClassInfo or old InnerClasses
Collection<InnerClass> classes = buildInnerClasses(referencedClasses);
if (classes.isEmpty()) {
return null;
}
InnerClass[] ics = null;
ics = classes.toArray(ics);
int length = ics.length * 8 + 2;
return new InnerClasses(cpg.addUtf8("InnerClasses"), length, ics, cpg.getConstantPool());
}
Aggregations