Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 382907

Summary: IMethodBinding.isSubsignature returns wrong results with generics
Product: [Eclipse Project] JDT Reporter: Jacek Sieka <arnetheduck>
Component: CoreAssignee: Jay Arthanareeswaran <jarthana>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: jarthana, srikanth_sankaran
Version: 3.8   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard: stalebug
Attachments:
Description Flags
Test case none

Description Jacek Sieka CLA 2012-06-18 17:08:36 EDT
Build Identifier: Version: 3.7.2 Build id: M20120208-0800

I have the following two classes:

public class Implement {
	public interface I<T> {
		void m(T t);

		T m2();
	}

	public static class S<T> implements I<T> {
		@Override
		public void m(T t) {
		}

		@Override
		public T m2() {
			return null;
		}
	}
}


public class BaseCall {
	public interface I<T> extends Implement.I<T> {
		@Override
		void m(T t);

		@Override
		T m2();
	}

	public static class X<T> extends Implement.S<T> implements I<T> {
	}
}


If I parse them using ASTParser, then call isSubsignature on the method binding of BaseCall.I<T>.m(T t) with Implement.S<T>.m(T t) as parameter, false is returned.

If I remove all generics (remove all <T>), true is returned instead as expected (as the method Implements.S.m(T t) provides the implementation for BaseCall.I<T> as well)

Reproducible: Always

Steps to Reproduce:
1. Get IMethodBinding mb for BaseCall.I<T>.m(T t) (using getInterfaces()[x].getDeclaredMethods() on ITypeBinding for BaseCall.X<T>)

2. Get IMethodBinding sm for Implement.S<T>.m(T t) (using getSuperclass().getDeclaredMethods() on ITypeBinding for BaseCall.X<T>)

3. Call sm.isSubsignature(mb)

I expect 3. to return true, it returns false.

Removing all generics causes it to return true as expected.
Comment 1 Srikanth Sankaran CLA 2012-06-19 00:29:50 EDT
(In reply to comment #0)

> If I parse them using ASTParser, then call isSubsignature on the method binding
> of BaseCall.I<T>.m(T t) with Implement.S<T>.m(T t) as parameter, false is
> returned.

Could you please attach a snippet that shows the problem ? Thanks.
Comment 2 Jacek Sieka CLA 2012-08-16 16:34:22 EDT
What should the snippet do? I've provided an example class that shows the bad behaviour and you can verify it with the ASTView plugin. A snippet would have to set up the whole ASTParser bits which I assume you have unit tests for already..
Comment 3 Jay Arthanareeswaran CLA 2012-09-25 04:07:25 EDT
Created attachment 221454 [details]
Test case

I have put the test case given in comment #0 in a junit test case, which fails currently.
Comment 4 Jay Arthanareeswaran CLA 2012-09-26 10:21:24 EDT
(In reply to comment #0)
> Steps to Reproduce:
> 1. Get IMethodBinding mb for BaseCall.I<T>.m(T t) (using
> getInterfaces()[x].getDeclaredMethods() on ITypeBinding for BaseCall.X<T>)
> 
> 2. Get IMethodBinding sm for Implement.S<T>.m(T t) (using
> getSuperclass().getDeclaredMethods() on ITypeBinding for BaseCall.X<T>)
> 
> 3. Call sm.isSubsignature(mb)
> 
> I expect 3. to return true, it returns false.

I just noticed that you are invoking isSubsignature on the inherited method and not on the inheriting method. For the test case I attached earlier, if I change the assertion to mb.isSubsignature(sm), the test pass.
Comment 5 Jacek Sieka CLA 2012-09-26 16:30:02 EDT
(In reply to comment #4)

> I just noticed that you are invoking isSubsignature on the inherited method
> and not on the inheriting method. For the test case I attached earlier, if I
> change the assertion to mb.isSubsignature(sm), the test pass.

My reading of 8.4.2 in JLS3 is that the notion of "same arguments" is symmetric, i e the order of comparison is not important, for non-erased types/methods (the first case in the definition of subsignature)..
Comment 6 Jay Arthanareeswaran CLA 2012-09-27 05:59:04 EDT
(In reply to comment #5)
> My reading of 8.4.2 in JLS3 is that the notion of "same arguments" is
> symmetric, i e the order of comparison is not important, for non-erased
> types/methods (the first case in the definition of subsignature)..

This is from the spec:
"The signature of a method m1 is a subsignature of the signature of a method
m2 if either
◆ m2 has the same signature as m1, or
◆ the signature of m1 is the same as the erasure of the signature of m2."

But it goes on to say:
"The notion of subsignature defined here is designed to express a relationship between two
methods whose signatures are not identical, but in which one may override the other."

Anyway, in JDT code, I do see some code deliberately trying to see if the 'other' method is from the super class/interface. And this behavior has been around at least since 3.7.
Comment 7 Eclipse Genie CLA 2019-12-08 12:38:06 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.