Blob Blame History Raw
### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.core
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java,v
retrieving revision 1.111.2.2
diff -u -r1.111.2.2 BinaryTypeBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java	23 Oct 2008 07:14:42 -0000	1.111.2.2
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java	3 Mar 2009 16:39:27 -0000
@@ -243,91 +243,101 @@
 	return availableMethods;
 }
 void cachePartsFrom(IBinaryType binaryType, boolean needFieldsAndMethods) {
-	// default initialization for super-interfaces early, in case some aborting compilation error occurs,
-	// and still want to use binaries passed that point (e.g. type hierarchy resolver, see bug 63748).
-	this.typeVariables = Binding.NO_TYPE_VARIABLES;
-	this.superInterfaces = Binding.NO_SUPERINTERFACES;
-
-	// must retrieve member types in case superclass/interfaces need them
-	this.memberTypes = Binding.NO_MEMBER_TYPES;
-	IBinaryNestedType[] memberTypeStructures = binaryType.getMemberTypes();
-	if (memberTypeStructures != null) {
-		int size = memberTypeStructures.length;
-		if (size > 0) {
-			this.memberTypes = new ReferenceBinding[size];
-			for (int i = 0; i < size; i++)
-				// attempt to find each member type if it exists in the cache (otherwise - resolve it when requested)
-				this.memberTypes[i] = environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1, false, null /* could not be missing */);
-			this.tagBits |= 	TagBits.HasUnresolvedMemberTypes;
-		}
-	}
-
-	
-	long sourceLevel = environment.globalOptions.sourceLevel;
-	char[] typeSignature = null;
-	if (sourceLevel >= ClassFileConstants.JDK1_5) {
-		typeSignature = binaryType.getGenericSignature();
-		this.tagBits |= binaryType.getTagBits();
-	}
-	char[][][] missingTypeNames = binaryType.getMissingTypeNames();	
-	if (typeSignature == null) {
-		char[] superclassName = binaryType.getSuperclassName();
-		if (superclassName != null) {
-			// attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
-			this.superclass = environment.getTypeFromConstantPoolName(superclassName, 0, -1, false, missingTypeNames);
-			this.tagBits |= TagBits.HasUnresolvedSuperclass;
-		}
-
+	try {
+		// default initialization for super-interfaces early, in case some aborting compilation error occurs,
+		// and still want to use binaries passed that point (e.g. type hierarchy resolver, see bug 63748).
+		this.typeVariables = Binding.NO_TYPE_VARIABLES;
 		this.superInterfaces = Binding.NO_SUPERINTERFACES;
-		char[][] interfaceNames = binaryType.getInterfaceNames();
-		if (interfaceNames != null) {
-			int size = interfaceNames.length;
+
+		// must retrieve member types in case superclass/interfaces need them
+		this.memberTypes = Binding.NO_MEMBER_TYPES;
+		IBinaryNestedType[] memberTypeStructures = binaryType.getMemberTypes();
+		if (memberTypeStructures != null) {
+			int size = memberTypeStructures.length;
 			if (size > 0) {
-				this.superInterfaces = new ReferenceBinding[size];
+				this.memberTypes = new ReferenceBinding[size];
 				for (int i = 0; i < size; i++)
-					// attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
-					this.superInterfaces[i] = environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1, false, missingTypeNames);
-				this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
+					// attempt to find each member type if it exists in the cache (otherwise - resolve it when requested)
+					this.memberTypes[i] = environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1, false, null /* could not be missing */);
+				this.tagBits |= 	TagBits.HasUnresolvedMemberTypes;
 			}
 		}
-	} else {
-		// ClassSignature = ParameterPart(optional) super_TypeSignature interface_signature
-		SignatureWrapper wrapper = new SignatureWrapper(typeSignature);
-		if (wrapper.signature[wrapper.start] == '<') {
-			// ParameterPart = '<' ParameterSignature(s) '>'
-			wrapper.start++; // skip '<'
-			this.typeVariables = createTypeVariables(wrapper, true, missingTypeNames);
-			wrapper.start++; // skip '>'
-			this.tagBits |=  TagBits.HasUnresolvedTypeVariables;
-			this.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
-		}
 
-		// attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
-		this.superclass = (ReferenceBinding) environment.getTypeFromTypeSignature(wrapper, Binding.NO_TYPE_VARIABLES, this, missingTypeNames);
-		this.tagBits |= TagBits.HasUnresolvedSuperclass;
+		long sourceLevel = environment.globalOptions.sourceLevel;
+		char[] typeSignature = null;
+		if (sourceLevel >= ClassFileConstants.JDK1_5) {
+			typeSignature = binaryType.getGenericSignature();
+			this.tagBits |= binaryType.getTagBits();
+		}
+		char[][][] missingTypeNames = binaryType.getMissingTypeNames();	
+		if (typeSignature == null) {
+			char[] superclassName = binaryType.getSuperclassName();
+			if (superclassName != null) {
+				// attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
+				this.superclass = environment.getTypeFromConstantPoolName(superclassName, 0, -1, false, missingTypeNames);
+				this.tagBits |= TagBits.HasUnresolvedSuperclass;
+			}
+
+			this.superInterfaces = Binding.NO_SUPERINTERFACES;
+			char[][] interfaceNames = binaryType.getInterfaceNames();
+			if (interfaceNames != null) {
+				int size = interfaceNames.length;
+				if (size > 0) {
+					this.superInterfaces = new ReferenceBinding[size];
+					for (int i = 0; i < size; i++)
+						// attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
+						this.superInterfaces[i] = environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1, false, missingTypeNames);
+					this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
+				}
+			}
+		} else {
+			// ClassSignature = ParameterPart(optional) super_TypeSignature interface_signature
+			SignatureWrapper wrapper = new SignatureWrapper(typeSignature);
+			if (wrapper.signature[wrapper.start] == '<') {
+				// ParameterPart = '<' ParameterSignature(s) '>'
+				wrapper.start++; // skip '<'
+				this.typeVariables = createTypeVariables(wrapper, true, missingTypeNames);
+				wrapper.start++; // skip '>'
+				this.tagBits |=  TagBits.HasUnresolvedTypeVariables;
+				this.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+			}
+			TypeVariableBinding[] typeVars = Binding.NO_TYPE_VARIABLES;
+			char[] methodDescriptor = binaryType.getEnclosingMethod();
+			if (methodDescriptor != null) {
+				MethodBinding enclosingMethod = findMethod(methodDescriptor, missingTypeNames);
+				typeVars = enclosingMethod.typeVariables;
+			}
 
-		this.superInterfaces = Binding.NO_SUPERINTERFACES;
-		if (!wrapper.atEnd()) {
-			// attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
-			java.util.ArrayList types = new java.util.ArrayList(2);
-			do {
-				types.add(environment.getTypeFromTypeSignature(wrapper, Binding.NO_TYPE_VARIABLES, this, missingTypeNames));
-			} while (!wrapper.atEnd());
-			this.superInterfaces = new ReferenceBinding[types.size()];
-			types.toArray(this.superInterfaces);
-			this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
+			// attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
+			this.superclass = (ReferenceBinding) environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames);
+			this.tagBits |= TagBits.HasUnresolvedSuperclass;
+
+			this.superInterfaces = Binding.NO_SUPERINTERFACES;
+			if (!wrapper.atEnd()) {
+				// attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
+				java.util.ArrayList types = new java.util.ArrayList(2);
+				do {
+					types.add(environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames));
+				} while (!wrapper.atEnd());
+				this.superInterfaces = new ReferenceBinding[types.size()];
+				types.toArray(this.superInterfaces);
+				this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
+			}
 		}
-	}
 
-	if (needFieldsAndMethods) {
-		createFields(binaryType.getFields(), sourceLevel, missingTypeNames);
-		createMethods(binaryType.getMethods(), sourceLevel, missingTypeNames);
-	} else { // protect against incorrect use of the needFieldsAndMethods flag, see 48459
-		this.fields = Binding.NO_FIELDS;
-		this.methods = Binding.NO_METHODS;
-	}
-	if (this.environment.globalOptions.storeAnnotations)
-		setAnnotations(createAnnotations(binaryType.getAnnotations(), this.environment, missingTypeNames));	
+		if (needFieldsAndMethods) {
+			createFields(binaryType.getFields(), sourceLevel, missingTypeNames);
+			createMethods(binaryType.getMethods(), sourceLevel, missingTypeNames);
+		}
+		if (this.environment.globalOptions.storeAnnotations)
+			setAnnotations(createAnnotations(binaryType.getAnnotations(), this.environment, missingTypeNames));	
+	} finally {
+		// protect against incorrect use of the needFieldsAndMethods flag, see 48459
+		if (this.fields == null)
+			this.fields = Binding.NO_FIELDS;
+		if (this.methods == null)
+			this.methods = Binding.NO_METHODS;
+ 	}
 }
 private void createFields(IBinaryField[] iFields, long sourceLevel, char[][][] missingTypeNames) {
 	this.fields = Binding.NO_FIELDS;
@@ -647,6 +657,45 @@
 	this.tagBits |= TagBits.AreFieldsComplete;
 	return fields;
 }
+private MethodBinding findMethod(char[] methodDescriptor, char[][][] missingTypeNames) {
+	int index = -1;
+	while (methodDescriptor[++index] != '(') {
+		// empty
+	}
+	char[] selector = new char[index];
+	System.arraycopy(methodDescriptor, 0, selector, 0, index);
+	TypeBinding[] parameters = Binding.NO_PARAMETERS;
+	int numOfParams = 0;
+	char nextChar;
+	while ((nextChar = methodDescriptor[++index]) != ')') {
+		if (nextChar != '[') {
+			numOfParams++;
+			if (nextChar == 'L')
+				while ((nextChar = methodDescriptor[++index]) != ';'){/*empty*/}
+		}
+	}
+
+	int startIndex = 0;
+	if (numOfParams > 0) {
+		parameters = new TypeBinding[numOfParams];
+		index = 1;
+		int end = 0;   // first character is always '(' so skip it
+		for (int i = 0; i < numOfParams; i++) {
+			while ((nextChar = methodDescriptor[++end]) == '['){/*empty*/}
+			if (nextChar == 'L')
+				while ((nextChar = methodDescriptor[++end]) != ';'){/*empty*/}
+
+			if (i >= startIndex) {   // skip the synthetic arg if necessary
+				parameters[i - startIndex] = this.environment.getTypeFromSignature(methodDescriptor, index, end, false, this, missingTypeNames);
+			}
+			index = end + 1;
+		}
+	}
+
+	return CharOperation.equals(selector, TypeConstants.INIT)
+		? this.enclosingType.getExactConstructor(parameters)
+		: this.enclosingType.getExactMethod(selector, parameters, null);
+}
 /**
  * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
  */
Index: model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java,v
retrieving revision 1.37
diff -u -r1.37 HierarchyBinaryType.java
--- model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java	27 May 2008 23:40:22 -0000	1.37
+++ model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java	3 Mar 2009 16:39:27 -0000
@@ -51,6 +51,9 @@
 public IBinaryAnnotation[] getAnnotations() {
 	return null;
 }
+public char[] getEnclosingMethod() {
+	return null;
+}
 /**
  * Answer the resolved name of the enclosing type in the
  * class file format as specified in section 4.2 of the Java 2 VM spec
Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java,v
retrieving revision 1.41
diff -u -r1.41 CodeSnippetSkeleton.java
--- eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java	27 May 2008 22:27:12 -0000	1.41
+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java	3 Mar 2009 16:39:27 -0000
@@ -108,6 +108,9 @@
 public IBinaryAnnotation[] getAnnotations() {
 	return null;
 }
+public char[] getEnclosingMethod() {
+	return null;
+}
 public char[] getEnclosingTypeName() {
 	return null;
 }
Index: compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java,v
retrieving revision 1.85
diff -u -r1.85 ClassFileReader.java
--- compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java	27 May 2008 22:21:14 -0000	1.85
+++ compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java	3 Mar 2009 16:39:27 -0000
@@ -50,6 +50,7 @@
 	private long version;
 	private char[] enclosingTypeName;
 	private char[][][] missingTypeNames;
+	private int enclosingNameAndTypeIndex;
 	
 private static String printTypeModifiers(int modifiers) {
 	java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
@@ -276,8 +277,9 @@
 				case 'E' :
 					if (CharOperation.equals(attributeName, AttributeNamesConstants.EnclosingMethodName)) {
 						utf8Offset = 
-							constantPoolOffsets[u2At(constantPoolOffsets[u2At(readOffset + 6)] - structOffset + 1)] - structOffset; 
+							this.constantPoolOffsets[u2At(this.constantPoolOffsets[u2At(readOffset + 6)] + 1)];
 						this.enclosingTypeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+						this.enclosingNameAndTypeIndex = u2At(readOffset + 8);
 					}
 					break;
 				case 'D' :
@@ -445,6 +447,23 @@
 	return this.constantPoolOffsets;
 }
 
+public char[] getEnclosingMethod() {
+	if (this.enclosingNameAndTypeIndex <= 0) {
+		return null;
+	}
+	// read the name
+	StringBuffer buffer = new StringBuffer();
+	
+	int nameAndTypeOffset = this.constantPoolOffsets[this.enclosingNameAndTypeIndex];
+	int utf8Offset = this.constantPoolOffsets[u2At(nameAndTypeOffset + 1)];
+	buffer.append(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));
+
+	utf8Offset = this.constantPoolOffsets[u2At(nameAndTypeOffset + 3)];
+	buffer.append(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));
+
+	return String.valueOf(buffer).toCharArray();
+}
+
 /*
  * Answer the resolved compoundName of the enclosing type
  * or null if the receiver is a top level type.
Index: compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java,v
retrieving revision 1.30
diff -u -r1.30 IBinaryType.java
--- compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java	27 May 2008 22:21:14 -0000	1.30
+++ compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java	3 Mar 2009 16:39:27 -0000
@@ -24,6 +24,14 @@
 
 IBinaryAnnotation[] getAnnotations();
 /**
+ * Answer the enclosing method (including method selector and method descriptor), or
+ * null if none.
+ *
+ * For example, "foo()Ljava/lang/Object;V"
+ */
+
+char[] getEnclosingMethod();
+/**
  * Answer the resolved name of the enclosing type in the
  * class file format as specified in section 4.2 of the Java 2 VM spec
  * or null if the receiver is a top level type.