Bug 160089 - isAssignmentCompatible does not give expected result
Summary: isAssignmentCompatible does not give expected result
Status: RESOLVED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3 M3   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-06 16:18 EDT by Manish Bhargava CLA
Modified: 2006-10-23 23:05 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Manish Bhargava CLA 2006-10-06 16:18:20 EDT
I have a List binding and a Collection binding and am trying to see if they are compatible by using the call..isAssignmentCompatible  

It return false for both ways. I should get true for one atleast as I can do Collectio xxx = new ArrayList()

if (genericType.isAssignmentCompatible((ITypeBinding)mapping.get(COLLECTION_KEY))){
  many = true;
}

where genericType is 
------------------------------------------------
public interface java.util.List
	extends java.lang.Object
	implements : Collection<E>
/*   methods   */
boolean add(E) 
void add(int, E) 
boolean addAll(Collection<? extends E>) 
boolean addAll(int, Collection<? extends E>) 
void clear() 
boolean contains(java.lang.Object) 
boolean containsAll(Collection<?>) 
boolean equals(java.lang.Object) 
E get(int) 
int hashCode() 
int indexOf(java.lang.Object) 
boolean isEmpty() 
Iterator<E> iterator() 
int lastIndexOf(java.lang.Object) 
ListIterator<E> listIterator() 
ListIterator<E> listIterator(int) 
boolean remove(java.lang.Object) 
E remove(int) 
boolean removeAll(Collection<?>) 
boolean retainAll(Collection<?>) 
E set(int, E) 
int size() 
List<E> subList(int, int) 
java.lang.Object[] toArray() 
T[] toArray(T[]) 
-------------------------------
 and parameter passed to the api is

--------------------------------
public interface java.util.Collection
	extends java.lang.Object
	implements : Iterable<E>
/*   methods   */
int size() 
boolean isEmpty() 
boolean contains(Unresolved type java.lang.Object) 
Iterator<E> iterator() 
java.lang.Object[] toArray() 
T[] toArray(T[]) 
boolean add(E) 
boolean remove(Unresolved type java.lang.Object) 
boolean containsAll(Collection<?>) 
boolean addAll(Collection<? extends E>) 
boolean removeAll(Collection<?>) 
boolean retainAll(Collection<?>) 
void clear() 
boolean equals(Unresolved type java.lang.Object) 
int hashCode()
Comment 1 Olivier Thomann CLA 2006-10-06 16:21:08 EDT
Could you please provide the source that returns the List binding?
Thanks.
Comment 2 Manish Bhargava CLA 2006-10-06 16:39:43 EDT
The code basically introspects a java file and loads the binding and building a data struture. Here is the method that gets a field binding. its annotations and type of field.

public static Reference parseReference(IAnnotationBinding annotationBinding, IBinding fieldOrMethodBinding, ITypeBinding typeBinding) {
		IMemberValuePairBinding[] memberValuePairBindings = annotationBinding.getDeclaredMemberValuePairs();
		String referenceName = null;
		Boolean required = Boolean.FALSE;
		for (int k = 0; k < memberValuePairBindings.length; k++) {
			IMemberValuePairBinding memberValuePairBinding = memberValuePairBindings[k];
			if (memberValuePairBinding.getName().equals("name")) { //$NON-NLS-1$
				referenceName = (String) memberValuePairBinding.getValue();
			} else if (memberValuePairBinding.getName().equals("required")) { //$NON-NLS-1$
				required = (Boolean) memberValuePairBinding.getValue();
			}
		}    				
		
		if (referenceName == null) {
			referenceName = fieldOrMethodBinding.getName();
            if (fieldOrMethodBinding.getKind() == IBinding.METHOD &&
            		referenceName.startsWith(JavaCoreConstants.SET_METHOD_PREFIX)) {
                referenceName = JavaIntrospectionHelper.toReferenceName(referenceName);
            }
		}
		
		boolean many = false;
		ITypeBinding genericType = typeBinding.getErasure();
		
		if (genericType.isAssignmentCompatible((ITypeBinding)mapping.get(COLLECTION_KEY))) {
			many = true;
		}
			
		if (typeBinding.isParameterizedType()) {
			typeBinding = typeBinding.getTypeArguments()[0];
		}
		
		return createReference(referenceName, typeBinding.getQualifiedName(), required.booleanValue(), many);			
	}

Notice how I call getErasure() on the typeBinding. This is the type og the field.

Does this help?

Comment 3 Manish Bhargava CLA 2006-10-06 16:42:02 EDT
The mapping that you see if built by call to 

ASTParser parser = ASTParser.newParser(AST.JLS3);
		parser.setResolveBindings(true);
	    parser.setSource(iCompilationUnit);
	    parser.createASTs(new ICompilationUnit[] {iCompilationUnit}, (String[])keys.toArray(new String[keys.size()]), 
    			new ASTRequestor() {
    				public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
    					types.addAll(ast.types());						
					}

					public void acceptBinding(String bindingKey, IBinding binding) {						
    					mapping.put(bindingKey, binding);
    				}
    			}, null);

where key passed is 

public static final String COLLECTION_KEY = BindingKey.createTypeBindingKey("java.util.Collection");  //$NON-NLS-1$

Hope all this helps
Comment 4 Olivier Thomann CLA 2006-10-20 14:56:51 EDT
Is List used as a raw type?
Comment 5 Olivier Thomann CLA 2006-10-20 16:50:10 EDT
Added regression test org.eclipse.jdt.core.tests.dom.ASTConverter15Test#test0229.
It is disabled for now.
Jérôme,

It seems that the binding retrieved from the key can never be used inside isAsignmentCompatible since it corresponds to the type binding of the declaration.
The Collection binding from the second field type is a raw type binding and then the call works fine.

Don't we want to get the bindings from the key as raw type bindings instead of generic type bindings?
Comment 6 Olivier Thomann CLA 2006-10-23 23:05:31 EDT
If you define COLLECTION_KEY as:
public static final String COLLECTION_KEY =
createParameterizedTypeBindingKey(
     "Ljava/util/Collection<TE;>;", new String[] {})
This will return a raw type and this is what you want in order to use the isAssignmentCompatible call.
Closing as INVALID.
Added regression test org.eclipse.jdt.core.tests.dom.ASTConverter15Test#test0229