Bug 184293 - Unnecessary inherited method errors reported against subtypes
Summary: Unnecessary inherited method errors reported against subtypes
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.3 M7   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-26 14:16 EDT by Kent Johnson CLA
Modified: 2007-05-03 20:49 EDT (History)
1 user (show)

See Also:


Attachments
Proposed patch (30.15 KB, patch)
2007-04-26 14:45 EDT, Kent Johnson CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Kent Johnson CLA 2007-04-26 14:16:22 EDT
Even prior to JDK1.5, we're reporting errors about inherited methods that are unnecessary.

For example, with this case:

class X extends S {
	public String foo(Number n) {return null;} // incompatible with T.foo()
}
abstract class Y extends S {} // complained about T.foo() & S.foo()

abstract class T {
	abstract Object foo(Number n);
}
abstract class S extends T {
	abstract String foo(Number n); // REAL problem is this method
}

The 2 errors reported against X & Y are unnecessary, as the real problem is the return type of S.foo() is not compatible with T.foo().

With the 1.5 verifier, the problem is worse because we needed to keep more inherited methods around to create bridge methods.
Comment 1 Kent Johnson CLA 2007-04-26 14:45:11 EDT
Created attachment 65087 [details]
Proposed patch
Comment 2 Kent Johnson CLA 2007-04-26 15:58:50 EDT
Maxime - please take a look & tell me what you think.
Comment 3 Maxime Daniel CLA 2007-04-27 03:38:23 EDT
Kent, interrupted by the verification start, just dumping my thoughts so far:

- I believe that the test toSkip[i] == -1 on MethodVerifier#600 never yields true, because you only happen to set toSkip[i] (never toSkip[j], that could be forward, hence get the test to yield true); this does not break the code, but could be optimized out; (pls shout if I'm wrong);
- I wonder if we could not swap the isInterface test and the inner loop here (not counted what it saves or looses yet; also wondering if we have stats available about a potential ordering of classes/interfaces in the methods array - I mean, do we have some chances that inheriting more often come first, or inherited more often come first):
	if (length > 1) {
		for (int i = 0; i < length; i++) {
			if (toSkip != null && toSkip[i] == -1) continue; // because extends is transitive (anyone which overrides i overrides anyone i overrides and marked it as such)
			ReferenceBinding declaringClass = methods[i].declaringClass;
			for (int j = i + 1; j < length; j++) {
				ReferenceBinding declaringClass2 = methods[j].declaringClass;
				if (declaringClass.isInterface()) {
					if (declaringClass2.isInterface()) {
						if (declaringClass.implementsInterface(declaringClass2, true)) {
							if (toSkip == null)
								toSkip = new int[length];
							toSkip[j] = -1;
						} else if (declaringClass2.implementsInterface(declaringClass, true)) {
							if (toSkip == null)
								toSkip = new int[length];
							toSkip[i] = -1;
						}
					}
				} else if (!declaringClass2.isInterface()) {
					if (declaringClass2.isSuperclassOf(declaringClass)) {
						if (toSkip == null)
							toSkip = new int[length];
						toSkip[j] = -1;
					} else if (declaringClass.isSuperclassOf(declaringClass2)) {
						if (toSkip == null)
							toSkip = new int[length];
						toSkip[i] = -1;
					}
				}
			}
		}
	}
- I would suggest that you add a reference to this bug number to at least one of the test cases that illustrate the concern that probed you to open the bug, for the sake of cross referencing, or else that you add a specific regression test.
Comment 4 Kent Johnson CLA 2007-04-30 15:00:27 EDT
Released to HEAD for 3.3M7

Updated the loop in findOverriddenInheritedMethods() slightly.

This fix makes the one in bug 162073 obsolete
Comment 5 Maxime Daniel CLA 2007-05-02 03:15:59 EDT
I've ironed out some stats on findOverriddenInheritedMethods#length using a full source workspace. My findings on build I20070501-0010 were the following:
Full source workspace stats				
Length	1	2	3	TOTAL
Raw	64565	1627	5	66197
Percent	97,53%	2,46%	0,01%	100,00%

I believe this is worth some consideration. Since this bug is fixed, I opened bug 1850376 to that effect.

Otherwise, I think the move to cutting down the list of methods to examine upfront is a good idea, and the modifications you made to the loop go even beyond my expectations. Coming back after the battle was over, I did not make a systematic review of the remainder of the patch. I can still do it if you want me to.
Comment 6 Maik Schreiber CLA 2007-05-02 06:10:26 EDT
(In reply to comment #5)

Since bug #1850376 does not exist, bug #185037 looks like the correct one.
Comment 7 Maxime Daniel CLA 2007-05-02 09:35:10 EDT
(In reply to comment #6)
> Since bug #1850376 does not exist, bug #185037 looks like the correct one.
Yeah. Typo. Thx for pointing it out.

Comment 8 Olivier Thomann CLA 2007-05-03 20:49:59 EDT
Verified for 3.3M7 with I20070503-1400.