[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Made a fix, not shure how to submit

Hello,

I made a fix for "weaver" that allows finding outer class from inner
class when inner class name does not follow javac name mangling
convention (for example because it's produced by scalac).

Since there is no relevant bug, should I open one and attach a patch, or
should I just post it here? In the second case, the patch is attached.

Linas.
### Eclipse Workspace Patch 1.0
#P weaver
Index: src/org/aspectj/weaver/bcel/BcelObjectType.java
===================================================================
RCS file: /cvsroot/tools/org.aspectj/modules/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java,v
retrieving revision 1.82
diff -u -r1.82 BcelObjectType.java
--- src/org/aspectj/weaver/bcel/BcelObjectType.java	24 Aug 2009 18:07:09 -0000	1.82
+++ src/org/aspectj/weaver/bcel/BcelObjectType.java	30 Aug 2009 13:31:27 -0000
@@ -23,8 +23,14 @@
 import java.util.List;
 import java.util.Set;
 
+import org.aspectj.apache.bcel.classfile.Attribute;
 import org.aspectj.apache.bcel.classfile.AttributeUtils;
+import org.aspectj.apache.bcel.classfile.ConstantClass;
+import org.aspectj.apache.bcel.classfile.ConstantString;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
 import org.aspectj.apache.bcel.classfile.Field;
+import org.aspectj.apache.bcel.classfile.InnerClass;
+import org.aspectj.apache.bcel.classfile.InnerClasses;
 import org.aspectj.apache.bcel.classfile.JavaClass;
 import org.aspectj.apache.bcel.classfile.Method;
 import org.aspectj.apache.bcel.classfile.Signature;
@@ -805,6 +811,52 @@
 	public ResolvedType getOuterClass() {
 		if (!isNested())
 			throw new IllegalStateException("Can't get the outer class of a non-nested type");
+		
+		//try finding outer class name from InnerClasses attribute assigned to this class
+		Attribute[] attrs = javaClass.getAttributes();
+		for( int attrIndex = 0; attrIndex < attrs.length; attrIndex++ ){
+			if( attrs[attrIndex] instanceof InnerClasses ){
+				//search for InnerClass entry that has current class as inner and some other class as outer
+				InnerClass[] innerClss = ((InnerClasses)attrs[attrIndex]).getInnerClasses();
+				
+				for( int innerClsIndex = 0; innerClsIndex < innerClss.length; innerClsIndex++ ){
+					InnerClass innerCls = innerClss[innerClsIndex];
+					
+					//skip entries that miss any necessary component, 0 index means "undefined", from JVM Spec 2nd ed. par. 4.7.5
+					if( innerCls.getInnerClassIndex() == 0 || innerCls.getOuterClassIndex() == 0 ) continue;
+					
+					//resolve inner class name, check if it matches current class name
+					ConstantClass innerClsInfo = (ConstantClass)javaClass
+						.getConstantPool()
+						.getConstant(innerCls.getInnerClassIndex());
+					
+					String innerClsName = ((ConstantUtf8)javaClass
+						.getConstantPool()
+						.getConstant(innerClsInfo.getNameIndex()))
+						.getBytes()
+						.replace('/', '.');   //class names in constant pool use '/' instead of '.', from JVM Spec 2nd ed. par. 4.2
+					
+					if( innerClsName.compareTo(className) == 0 ){
+						//resolve outer class name 
+						ConstantClass outerClsInfo = (ConstantClass)javaClass
+							.getConstantPool()
+							.getConstant(innerCls.getOuterClassIndex());
+						
+						String outerClsName = ((ConstantUtf8)javaClass
+							.getConstantPool()
+							.getConstant(outerClsInfo.getNameIndex()))
+							.getBytes()
+							.replace('/', '.');   //class names in constant pool use '/' instead of '.', from JVM Spec 2nd ed. par. 4.2
+						
+						//
+						UnresolvedType outer = UnresolvedType.forName(outerClsName);
+						return outer.resolve(getResolvedTypeX().getWorld());
+					}
+				}
+			}
+		}
+		
+		//try finding outer class name by assuming standard class name mangling convention of javac for this class
 		int lastDollar = className.lastIndexOf('$');
 		String superClassName = className.substring(0, lastDollar);
 		UnresolvedType outer = UnresolvedType.forName(superClassName);