Adjustments to account for changes in JDT:
* abandon testing with compliance 1.5 which had problems
with @Override due to changes in StubUtility2Core
* consequence of above: one null-quickfix is no longer observed
as it is not yet implemented for TYPE_USE annotations
* Replace adaptation in StubUtility2Core with minimal fixes
- add more tests for quickfix re unimplemented methods
- let dom TypeBinding find relevant synth super interfaces
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 9f9f28e..4b9d720 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -59,6 +59,8 @@
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
+import static org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals;
+
/**
* <h4>OTDT changes:</h4>
* <dl>
@@ -604,7 +606,10 @@
*/
for (int i = 0; i < length; i++) {
// OT: look into synthetic role interfaces:
- if (internalInterfaces[i].isSynthInterface()) {
+ RoleModel roleModel = referenceBinding.roleModel;
+ if (roleModel != null
+ && internalInterfaces[i].isSynthInterface()
+ && equalsEquals(internalInterfaces[i], roleModel.getInterfacePartBinding())) {
try {
// mini version of the outer loop:
ReferenceBinding[] transitiveInterfaces = internalInterfaces[i].superInterfaces();
diff --git a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/CompletionAdaptor/StubUtility2Core.java b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/CompletionAdaptor/StubUtility2Core.java
index 42cc3c1..a473a30 100644
--- a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/CompletionAdaptor/StubUtility2Core.java
+++ b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/CompletionAdaptor/StubUtility2Core.java
@@ -18,13 +18,8 @@
**********************************************************************/
team package org.eclipse.objectteams.otdt.internal.ui.assist.CompletionAdaptor;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
import org.eclipse.jdt.core.dom.IMethodBinding;
-import org.eclipse.jdt.core.dom.IPackageBinding;
-import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Modifier;
/**
@@ -32,104 +27,25 @@
* @author stephan
* @since 2.7.2 (separated out from sibling StubUtility2 due to code move from jdt.ui to jdt.core.manipulation)
*/
-@SuppressWarnings({ "unchecked", "rawtypes"/*parameter-less lists from DOM*/, "decapsulation"/*final baseclass + callout-decapsulation*/})
+@SuppressWarnings({ "decapsulation"/*final baseclass*/})
protected class StubUtility2Core playedBy StubUtility2Core
{
+ isStatic <- replace isStatic;
+ isPrivate <- replace isPrivate;
- // CALLOUT INTERFACE:
- void findUnimplementedInterfaceMethods(ITypeBinding typeBinding, HashSet<ITypeBinding> visited, ArrayList<IMethodBinding> allMethods, IPackageBinding currPack, ArrayList<IMethodBinding> toImplement)
- -> void findUnimplementedInterfaceMethods(ITypeBinding typeBinding, HashSet<ITypeBinding> visited, ArrayList<IMethodBinding> allMethods, IPackageBinding currPack, ArrayList<IMethodBinding> toImplement);
- IMethodBinding findMethodBinding(IMethodBinding method, List<IMethodBinding> allMethods)
- -> IMethodBinding findMethodBinding(IMethodBinding method, List<IMethodBinding> allMethods);
-
- /**
- * This callin adds treatment of implicit inheritance including phantom roles
- * to it's base version.
- */
- IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding, boolean implementAbstractsOfInput)
- <- replace IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding, boolean implementAbstractsOfInput);
@SuppressWarnings("basecall")
- callin static IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding, boolean implementAbstractsOfInput) {
- // COPY&PASTE from base version:
- ArrayList<IMethodBinding> allMethods= new ArrayList<>();
- ArrayList<IMethodBinding> toImplement= new ArrayList<>();
-
- for (IMethodBinding curr : typeBinding.getDeclaredMethods()) {
- int modifiers= curr.getModifiers();
- if (!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)
- && !curr.isSyntheticRecordMethod()) {
-//{ObjectTeams: never enter copied methods (have no java element)
- if (!curr.isCopied())
-// SH}
- allMethods.add(curr);
- }
+ static callin boolean isStatic(IMethodBinding method) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ // our base is interested only in 'normal' static methods, not counting abstract static role methods
+ return !Modifier.isAbstract(method.getModifiers());
}
-//{ObjectTeams: direct tsuper roles:
- ITypeBinding[] tsupers= typeBinding.getSuperRoles();
- if (tsupers != null)
- for (ITypeBinding tsuperRole : tsupers)
- findVisibleVirtualMethods(tsuperRole, allMethods);
-// SH}
-
- ITypeBinding superClass= typeBinding.getSuperclass();
- while (superClass != null) {
-//{ObjectTeams: watch for phantom roles (which don't exist):
- if (superClass.getJavaElement().exists()) {
- // extracted orig:
- findVisibleVirtualMethods(superClass, allMethods);
- } else {
- // proceed to the existing super of a phantom role:
- tsupers= superClass.getSuperRoles();
- if (tsupers != null)
- for (ITypeBinding tsuperRole : tsupers)
- findVisibleVirtualMethods(tsuperRole, allMethods);
- }
-// SH}
- superClass= superClass.getSuperclass();
- }
-
- for (IMethodBinding curr : allMethods) {
- int modifiers= curr.getModifiers();
- if ((Modifier.isAbstract(modifiers) || curr.getDeclaringClass().isInterface()) && (implementAbstractsOfInput || typeBinding != curr.getDeclaringClass())) {
- // implement all abstract methods
- toImplement.add(curr);
- }
- }
-
- HashSet<ITypeBinding> visited= new HashSet<>();
- ITypeBinding curr= typeBinding;
- while (curr != null) {
- for (ITypeBinding superInterface : curr.getInterfaces()) {
-//{ObjectTeams: consider that a role class part finds its super interfaces in the interface part:
- if (curr.isClassPartOf(superInterface)) {
- // do consider transitively inherited methods:
- ITypeBinding[] superSuperInterfaces = superInterface.getInterfaces();
- for (ITypeBinding superSuperIfc : superSuperInterfaces)
- findUnimplementedInterfaceMethods(superSuperIfc, visited, allMethods, typeBinding.getPackage(), toImplement);
- // but don't add methods from our own ifc-part (occurs when role extends non-role).
- continue;
- }
-// SH}
- findUnimplementedInterfaceMethods(superInterface, visited, allMethods, typeBinding.getPackage(), toImplement);
- }
- curr= curr.getSuperclass();
- }
-
- return toImplement.toArray(new IMethodBinding[toImplement.size()]);
+ return false;
}
- // COPY&PASTE: orig extracted as helper from base of above:
- private static void findVisibleVirtualMethods(ITypeBinding typeBinding, ArrayList<IMethodBinding> allMethods) {
- for (IMethodBinding curr : typeBinding.getDeclaredMethods()) {
- int modifiers= curr.getModifiers();
- if ((!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers))
- || Modifier.isAbstract(modifiers)) // OT: account for 'abstract static' (partially virtual ;P )
- {
- if (!curr.isCopied()) // new check for OT
- if (findMethodBinding(curr, allMethods) == null) {
- allMethods.add(curr);
- }
- }
- }
+
+ // FIXME: temp fix for JDT-UI bug:
+ @SuppressWarnings("basecall")
+ static callin boolean isPrivate(IMethodBinding method) {
+ return Modifier.isPrivate(method.getModifiers());
}
}
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/JavaQuickFixTests.java b/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/JavaQuickFixTests.java
index ab1ec54..08c5339 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/JavaQuickFixTests.java
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/JavaQuickFixTests.java
@@ -43,6 +43,7 @@
import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal;
import org.eclipse.jdt.ui.text.java.correction.ChangeCorrectionProposal;
import org.eclipse.objectteams.otdt.core.ext.OTDTPlugin;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -317,7 +318,263 @@
assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
}
+ // Bug 348574 - [quickfix] implement abstract methods from tsuper
+ // challenge inheritance via phantom role
@Test
+ public void testAddAbstractMethods1_phantom() throws CoreException {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends T1 {\n");
+ buf.append(" protected class R2 extends R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu1=pack1.createCompilationUnit("T2.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T1 {\n");
+ buf.append(" abstract protected class R {\n");
+ buf.append(" abstract void foo() {}\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ pack1.createCompilationUnit("T1.java", buf.toString(), false, null);
+
+ CompilationUnit astRoot= getASTRoot(cu1);
+ ArrayList<IJavaCompletionProposal> proposals1= collectCorrections(cu1, astRoot, 1, 0);
+ assertNumberOfProposals(proposals1, 2);
+ assertCorrectLabels(proposals1);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals1.get(0);
+ String preview1= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends T1 {\n");
+ buf.append(" protected class R2 extends R {\n");
+ buf.append("\n");
+ buf.append(" @Override\n");
+ buf.append(" void foo() {\n");
+ buf.append(" // TODO Auto-generated method stub\n");
+ buf.append(" \n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+
+ proposal= (CUCorrectionProposal) proposals1.get(1);
+ String preview2= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends T1 {\n");
+ buf.append(" protected abstract class R2 extends R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected2= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+ }
+
+ // Bug 348574 - [quickfix] implement abstract methods from tsuper
+ // abstract static method
+ // challenge inheritance via phantom role
+ @Test
+ public void testAddAbstractMethods2_phantom() throws CoreException {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends T1 {\n");
+ buf.append(" protected class R2 extends R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu1=pack1.createCompilationUnit("T2.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T1 {\n");
+ buf.append(" abstract protected class R {\n");
+ buf.append(" abstract static void foo() {}\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ pack1.createCompilationUnit("T1.java", buf.toString(), false, null);
+
+ CompilationUnit astRoot= getASTRoot(cu1);
+ ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu1, astRoot, 1, 0);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+ String preview1= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends T1 {\n");
+ buf.append(" protected class R2 extends R {\n");
+ buf.append("\n");
+ buf.append(" @Override\n");
+ buf.append(" static void foo() {\n");
+ buf.append(" // TODO Auto-generated method stub\n");
+ buf.append(" \n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+
+ proposal= (CUCorrectionProposal) proposals.get(1);
+ String preview2= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends T1 {\n");
+ buf.append(" protected abstract class R2 extends R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected2= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+ }
+
+ // Bug 348574 - [quickfix] implement abstract methods from tsuper
+ // challenge implicit inheritance via phantom role
+ @Test
+ public void testAddAbstractMethods1_3teams() throws CoreException {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends TMid {\n");
+ buf.append(" protected class R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu1=pack1.createCompilationUnit("T2.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T1 {\n");
+ buf.append(" abstract protected class R {\n");
+ buf.append(" abstract void foo() {}\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ pack1.createCompilationUnit("T1.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class TMid extends T1 {\n");
+ buf.append("}\n");
+ pack1.createCompilationUnit("TMid.java", buf.toString(), false, null);
+
+ CompilationUnit astRoot= getASTRoot(cu1);
+ ArrayList<IJavaCompletionProposal> proposals1= collectCorrections(cu1, astRoot, 2, 0);
+ assertNumberOfProposals(proposals1, 0);
+ ArrayList<IJavaCompletionProposal> proposals2= collectCorrections(cu1, astRoot, 2, 1);
+ assertNumberOfProposals(proposals2, 2);
+ assertCorrectLabels(proposals1);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals2.get(0);
+ String preview1= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends TMid {\n");
+ buf.append(" protected class R {\n");
+ buf.append("\n");
+ buf.append(" @Override\n");
+ buf.append(" void foo() {\n");
+ buf.append(" // TODO Auto-generated method stub\n");
+ buf.append(" \n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+
+ proposal= (CUCorrectionProposal) proposals2.get(1);
+ String preview2= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends TMid {\n");
+ buf.append(" protected abstract class R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected2= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+ }
+
+
+ // Bug 348574 - [quickfix] implement abstract methods from tsuper
+ // abstract static method
+ // challenge implicit inheritance via phantom role
+ @Test
+ public void testAddAbstractMethods2_3teams() throws CoreException {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends TMid {\n");
+ buf.append(" protected class R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu1=pack1.createCompilationUnit("T2.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T1 {\n");
+ buf.append(" abstract protected class R {\n");
+ buf.append(" abstract static void foo() {}\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ pack1.createCompilationUnit("T1.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class TMid extends T1 {\n");
+ buf.append("}\n");
+ pack1.createCompilationUnit("TMid.java", buf.toString(), false, null);
+
+ CompilationUnit astRoot= getASTRoot(cu1);
+ ArrayList<IJavaCompletionProposal> proposals1= collectCorrections(cu1, astRoot, 2, 0);
+ assertNumberOfProposals(proposals1, 0);
+ ArrayList<IJavaCompletionProposal> proposals2= collectCorrections(cu1, astRoot, 2, 1);
+ assertNumberOfProposals(proposals2, 2);
+ assertCorrectLabels(proposals1);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals2.get(0);
+ String preview1= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends TMid {\n");
+ buf.append(" protected class R {\n");
+ buf.append("\n");
+ buf.append(" @Override\n");
+ buf.append(" static void foo() {\n");
+ buf.append(" // TODO Auto-generated method stub\n");
+ buf.append(" \n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+
+ proposal= (CUCorrectionProposal) proposals2.get(1);
+ String preview2= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public team class T2 extends TMid {\n");
+ buf.append(" protected abstract class R {\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected2= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+ }
+
+ @Test
+ @Ignore("this quickfix is currently not available with TYPE_USE annotations")
public void testExtractPotentiallyNullField1() throws Exception {
setupForNullAnnotations(true/*plainJava*/);
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/OTQuickFixTest.java b/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/OTQuickFixTest.java
index 51a8574..5d8079b 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/OTQuickFixTest.java
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/OTQuickFixTest.java
@@ -97,6 +97,9 @@
IProjectDescription description = fJProject1.getProject().getDescription();
description.setNatureIds(OTDTPlugin.createProjectNatures(description));
fJProject1.getProject().setDescription(description, null);
+ fJProject1.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
+ fJProject1.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
+ fJProject1.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
OTREContainer.initializeOTJProject(fJProject1.getProject());
}