Fixed Bug 438812 - Missing bridge methods in indirect child classes with
ECJ 3.10.0

Signed-off-by: Sasikanth Bharadwaj <saammana@in.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index 9a3803a..e7ddde8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -32815,19 +32815,29 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=140643
 public void test0987() {
 	String expectedOutput = new CompilerOptions(getCompilerOptions()).sourceLevel < ClassFileConstants.JDK1_6
-    ?	"----------\n" + 
-		"1. ERROR in X.java (at line 11)\n" + 
+    ?	"----------\n" +
+		"1. ERROR in X.java (at line 7)\n" + 
+		"	abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" + 
+		"	               ^^^^^^^^^^^^^^^^\n" + 
+		"The return types are incompatible for the inherited methods EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 11)\n" + 
 		"	public ISheetViewer getViewer() { return null; }	\n" + 
 		"	       ^^^^^^^^^^^^\n" + 
 		"The return type is incompatible with EditPart.getViewer()\n" + 
 		"----------\n" + 
-		"2. ERROR in X.java (at line 11)\n" + 
+		"3. ERROR in X.java (at line 11)\n" + 
 		"	public ISheetViewer getViewer() { return null; }	\n" + 
 		"	                    ^^^^^^^^^^^\n" + 
 		"The method getViewer() of type AbstractLinkView<M> must override a superclass method\n" + 
 		"----------\n"
-    :		"----------\n" + 
-		"1. ERROR in X.java (at line 11)\n" + 
+    :	"----------\n" + 
+		"1. ERROR in X.java (at line 7)\n" + 
+		"	abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" + 
+		"	               ^^^^^^^^^^^^^^^^\n" + 
+		"The return types are incompatible for the inherited methods EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 11)\n" + 
 		"	public ISheetViewer getViewer() { return null; }	\n" + 
 		"	       ^^^^^^^^^^^^\n" + 
 		"The return type is incompatible with EditPart.getViewer()\n" + 
@@ -32916,7 +32926,12 @@
 				"}", // =================
 			},
 			"----------\n" +
-			"1. ERROR in X.java (at line 11)\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" + 
+			"	               ^^^^^^^^^^^^^^^^\n" + 
+			"The return types are incompatible for the inherited methods ILinkViewElement.getViewer(), EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 11)\n" + 
 			"	public SheetViewer getViewer() { return null; }	\n" + 
 			"	       ^^^^^^^^^^^\n" + 
 			"The return type is incompatible with AbstractEditPart.getViewer()\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
index fcdbd8b..ae8357b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
@@ -14079,4 +14079,39 @@
 		},
 		"CCC");
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=438812, Missing bridge methods in indirect child classes with ECJ 3.10.0
+public void testBug438812() throws Exception {
+	this.runConformTest(
+		new String[] {
+			"A.java",
+			"import java.util.Collection;\n" + 
+			"import java.util.List;\n" + 
+			"\n" + 
+			"public interface A {\n" + 
+			"    Iterable getIterable();\n" + 
+			"}\n" + 
+			"\n" + 
+			"class B implements A {\n" + 
+			"    public Collection getIterable() { return null; }\n" + 
+			"}\n" + 
+			"\n" + 
+			"class C extends B {\n" + 
+			"    public List getIterable() { return null; }\n" + 
+			"}",
+		},
+		"");
+	String expectedOutput = "  public bridge synthetic java.lang.Iterable getIterable();";
+
+	File f = new File(OUTPUT_DIR + File.separator + "C.class");
+	byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
+	ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+	String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
+	int index = result.indexOf(expectedOutput);
+	if (index == -1 || expectedOutput.length() == 0) {
+		System.out.println(Util.displayString(result, 3));
+	}
+	if (index == -1) {
+		assertEquals("Wrong contents", expectedOutput, result);
+	}
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index ab9cc05..b539287 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -950,11 +950,15 @@
 		return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary
 
 	inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod);
-	return inheritedMethod != null
-		&& (TypeBinding.equalsEquals(inheritedMethod.returnType, existingMethod.returnType)	// need to keep around to produce bridge methods? ...
-			|| (TypeBinding.notEquals(this.type, existingMethod.declaringClass) 			// ... not if inheriting the bridge situation from a superclass
-					&& !existingMethod.declaringClass.isInterface()))
-		&& doesMethodOverride(existingMethod, inheritedMethod);
+	if (inheritedMethod == null
+			|| TypeBinding.notEquals(inheritedMethod.returnType, existingMethod.returnType)) // need to keep around to produce bridge methods? ...
+		return false;
+
+	if (!doesMethodOverride(existingMethod, inheritedMethod))
+		return false;
+
+	return TypeBinding.notEquals(this.type, existingMethod.declaringClass) // ... not if inheriting the bridge situation from a superclass
+			&& !existingMethod.declaringClass.isInterface();
 }
 public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
 	if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))