diff options
| author | Noopur Gupta | 2015-03-05 18:49:08 +0000 |
|---|---|---|
| committer | Markus Keller | 2015-03-05 18:49:08 +0000 |
| commit | 2586520eea42ad7e97773c3bef22574c5df5c1ba (patch) | |
| tree | 73a666eea2d88bf0651bd5ab297bbab3afb7f03f | |
| parent | 2d7e1be4fd729c6996dc3ae6518b65b35b92509f (diff) | |
| download | eclipse.jdt.ui-2586520eea42ad7e97773c3bef22574c5df5c1ba.tar.gz eclipse.jdt.ui-2586520eea42ad7e97773c3bef22574c5df5c1ba.tar.xz eclipse.jdt.ui-2586520eea42ad7e97773c3bef22574c5df5c1ba.zip | |
Bug 460521: [1.8][override method] Override / Implement methods should offer to generate default methodsI20150310-0800
Also removed the redundant "public" modifier that was generated by StubUtility2#getImplementationModifiers(..)
Also-by: Markus Keller <markus_keller@ch.ibm.com>
5 files changed, 261 insertions, 38 deletions
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest18.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest18.java index b4d7db211b..28050d970e 100644 --- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest18.java +++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest18.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014 GK Software AG, IBM Corporation and others. + * Copyright (c) 2014, 2015 GK Software AG, IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,9 +13,6 @@ package org.eclipse.jdt.text.tests.contentassist; import java.util.Hashtable; -import junit.framework.Test; -import junit.framework.TestSuite; - import org.eclipse.jdt.testplugin.JavaProjectHelper; import org.eclipse.jdt.testplugin.TestOptions; @@ -57,6 +54,9 @@ import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; +import junit.framework.Test; +import junit.framework.TestSuite; + public class CodeCompletionTest18 extends AbstractCompletionTest { private static final Class THIS= CodeCompletionTest18.class; @@ -280,7 +280,7 @@ public class CodeCompletionTest18 extends AbstractCompletionTest { buf.append(" * @see test1.Main.Foo#hello()\n"); buf.append(" */\n"); buf.append(" @Override\n"); - buf.append(" public default void hello() {\n"); + buf.append(" default void hello() {\n"); buf.append(" //TODO\n"); buf.append(" Foo.super.hello();\n"); buf.append(" }\n"); @@ -334,7 +334,7 @@ public class CodeCompletionTest18 extends AbstractCompletionTest { buf.append(" * @see test1.I#getSize(java.lang.String)\n"); buf.append(" */\n"); buf.append(" @Override\n"); - buf.append(" public default int getSize(String name) {\n"); + buf.append(" default int getSize(String name) {\n"); buf.append(" //TODO\n"); buf.append(" return I.super.getSize(name);\n"); buf.append(" }\n"); @@ -382,4 +382,235 @@ public class CodeCompletionTest18 extends AbstractCompletionTest { buf.append("}\n"); assertEquals(buf.toString(), doc.get()); } + + public void testOverride5() throws CoreException { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I1 {\n"); + buf.append(" equals\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("I1.java", buf.toString(), false, null); + + String str= "equals"; + int offset= buf.toString().indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + assertEquals(1, proposals.length); + IEditorPart part= JavaUI.openInEditor(cu); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I1 {\n"); + buf.append(" /* (non-Javadoc)\n"); + buf.append(" * @see java.lang.Object#equals(java.lang.Object)\n"); + buf.append(" */\n"); + buf.append(" @Override\n"); + buf.append(" boolean equals(Object arg0);\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testOverride6() throws CoreException { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I2 {\n"); + buf.append(" hashCode\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("I2.java", buf.toString(), false, null); + + String str= "hashCode"; + int offset= buf.toString().indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + assertEquals(1, proposals.length); + IEditorPart part= JavaUI.openInEditor(cu); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I2 {\n"); + buf.append(" /* (non-Javadoc)\n"); + buf.append(" * @see java.lang.Object#hashCode()\n"); + buf.append(" */\n"); + buf.append(" @Override\n"); + buf.append(" int hashCode();\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testOverride7() throws CoreException { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I3 {\n"); + buf.append(" toString\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("I3.java", buf.toString(), false, null); + + String str= "toString"; + int offset= buf.toString().indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + assertEquals(1, proposals.length); + IEditorPart part= JavaUI.openInEditor(cu); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I3 {\n"); + buf.append(" /* (non-Javadoc)\n"); + buf.append(" * @see java.lang.Object#toString()\n"); + buf.append(" */\n"); + buf.append(" @Override\n"); + buf.append(" String toString();\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testOverride8() throws CoreException { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I4 {\n"); + buf.append(" clone\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("I4.java", buf.toString(), false, null); + + String str= "clone"; + int offset= buf.toString().indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + assertEquals(3, proposals.length); + IEditorPart part= JavaUI.openInEditor(cu); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + proposals[2].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I4 {\n"); + buf.append(" /* (non-Javadoc)\n"); + buf.append(" * @see java.lang.Object#clone()\n"); + buf.append(" */\n"); + buf.append(" Object clone() throws CloneNotSupportedException;\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testOverride9() throws CoreException { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I5 {\n"); + buf.append(" finalize\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("I5.java", buf.toString(), false, null); + + String str= "finalize"; + int offset= buf.toString().indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + assertEquals(2, proposals.length); + IEditorPart part= JavaUI.openInEditor(cu); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + proposals[1].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I5 {\n"); + buf.append(" /* (non-Javadoc)\n"); + buf.append(" * @see java.lang.Object#finalize()\n"); + buf.append(" */\n"); + buf.append(" void finalize() throws Throwable;\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testOverride10() throws CoreException { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I6 extends A {\n"); + buf.append(" myAbs\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface A {\n"); + buf.append(" void myAbstractM();\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("I6.java", buf.toString(), false, null); + + String str= "myAbs"; + int offset= buf.toString().indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + assertEquals(2, proposals.length); + IEditorPart part= JavaUI.openInEditor(cu); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public interface I6 extends A {\n"); + buf.append(" /* (non-Javadoc)\n"); + buf.append(" * @see test1.A#myAbstractM()\n"); + buf.append(" */\n"); + buf.append(" @Override\n"); + buf.append(" default void myAbstractM() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface A {\n"); + buf.append(" void myAbstractM();\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } } diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java index 66c3f19f6c..f06ceeb72d 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2014 IBM Corporation and others. + * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -86,8 +86,8 @@ import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider; */ public final class StubUtility2 { - public static void addOverrideAnnotation(IJavaProject project, ASTRewrite rewrite, MethodDeclaration decl, IMethodBinding binding) { - if (binding.getDeclaringClass().isInterface()) { + public static void addOverrideAnnotation(IJavaProject project, ASTRewrite rewrite, MethodDeclaration decl, IMethodBinding overriddenMethod) { + if (overriddenMethod.getDeclaringClass().isInterface()) { String version= project.getOption(JavaCore.COMPILER_COMPLIANCE, true); if (JavaModelUtil.isVersionLessThan(version, JavaCore.VERSION_1_6)) return; // not allowed in 1.5 @@ -350,7 +350,9 @@ public final class StubUtility2 { String delimiter= unit.findRecommendedLineSeparator(); int modifiers= binding.getModifiers(); - if (!(inInterface && Modifier.isAbstract(modifiers))) { + ITypeBinding declaringType= binding.getDeclaringClass(); + ITypeBinding typeObject= ast.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ + if (!inInterface || (declaringType != typeObject && JavaModelUtil.is18OrHigher(javaProject))) { // generate a method body Map<String, String> options= javaProject.getOptions(true); @@ -368,7 +370,6 @@ public final class StubUtility2 { } } else { SuperMethodInvocation invocation= ast.newSuperMethodInvocation(); - ITypeBinding declaringType= binding.getDeclaringClass(); if (declaringType.isInterface()) { String qualifier= imports.addImport(declaringType.getErasure(), context); Name name= ASTNodeFactory.newName(ast, qualifier); @@ -405,7 +406,13 @@ public final class StubUtility2 { decl.setJavadoc(javadoc); } } - if (settings != null && settings.overrideAnnotation && JavaModelUtil.is50OrHigher(javaProject)) { + boolean overrideAnnotationRequired= settings != null && settings.overrideAnnotation && JavaModelUtil.is50OrHigher(javaProject); + if (inInterface && declaringType == typeObject && !Modifier.isPublic(modifiers)) { + // According to JLS8 9.2, an interface doesn't implicitly declare non-public members of Object, + // and JLS8 9.6.4.4 doesn't allow @Override for these methods (clone and finalize). + overrideAnnotationRequired= false; + } + if (overrideAnnotationRequired) { addOverrideAnnotation(javaProject, rewrite, decl, binding); } @@ -661,15 +668,16 @@ public final class StubUtility2 { private static List<IExtendedModifier> getImplementationModifiers(AST ast, IMethodBinding method, boolean inInterface, ImportRewrite importRewrite, ImportRewriteContext context) throws JavaModelException { IJavaProject javaProject= importRewrite.getCompilationUnit().getJavaProject(); - int modifiers= method.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.NATIVE & ~Modifier.PRIVATE; + int modifiers= method.getModifiers(); if (inInterface) { - modifiers= modifiers & ~Modifier.PROTECTED; - if (!method.getDeclaringClass().isInterface() ) { - modifiers= modifiers | Modifier.PUBLIC; + modifiers= modifiers & ~Modifier.PROTECTED & ~Modifier.PUBLIC; + if (Modifier.isAbstract(modifiers) && JavaModelUtil.is18OrHigher(javaProject)) { + modifiers= modifiers | Modifier.DEFAULT; } } else { modifiers= modifiers & ~Modifier.DEFAULT; } + modifiers= modifiers & ~Modifier.ABSTRACT & ~Modifier.NATIVE & ~Modifier.PRIVATE; IAnnotationBinding[] annotations= method.getAnnotations(); if (modifiers != Modifier.NONE && annotations.length > 0) { @@ -729,7 +737,7 @@ public final class StubUtility2 { IMethodBinding[] typeMethods= typeBinding.getDeclaredMethods(); for (int index= 0; index < typeMethods.length; index++) { final int modifiers= typeMethods[index].getModifiers(); - if (!typeMethods[index].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) + if (!typeMethods[index].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers) && !Modifier.isFinal(modifiers)) allMethods.add(typeMethods[index]); } ITypeBinding clazz= typeBinding.getSuperclass(); @@ -737,7 +745,7 @@ public final class StubUtility2 { IMethodBinding[] methods= clazz.getDeclaredMethods(); for (int offset= 0; offset < methods.length; offset++) { final int modifiers= methods[offset].getModifiers(); - if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { + if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers) && !Modifier.isFinal(modifiers)) { if (findOverridingMethod(methods[offset], allMethods) == null) allMethods.add(methods[offset]); } @@ -756,15 +764,6 @@ public final class StubUtility2 { getOverridableMethods(ast, ast.resolveWellKnownType("java.lang.Object"), allMethods); //$NON-NLS-1$ if (!isSubType) allMethods.removeAll(Arrays.asList(typeMethods)); - int modifiers= 0; - if (!typeBinding.isInterface()) { - for (int index= allMethods.size() - 1; index >= 0; index--) { - IMethodBinding method= allMethods.get(index); - modifiers= method.getModifiers(); - if (Modifier.isFinal(modifiers)) - allMethods.remove(index); - } - } return allMethods.toArray(new IMethodBinding[allMethods.size()]); } @@ -772,8 +771,8 @@ public final class StubUtility2 { IMethodBinding[] methods= superBinding.getDeclaredMethods(); for (int offset= 0; offset < methods.length; offset++) { final int modifiers= methods[offset].getModifiers(); - if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { - if (findOverridingMethod(methods[offset], allMethods) == null && !Modifier.isStatic(modifiers)) + if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers) && !Modifier.isFinal(modifiers)) { + if (findOverridingMethod(methods[offset], allMethods) == null) allMethods.add(methods[offset]); } } diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java index 20eeb40779..26186e8250 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -117,7 +117,6 @@ public final class ActionMessages extends NLS { public static String OverrideMethodsAction_error_title; public static String OverrideMethodsAction_error_nothing_found; public static String OverrideMethodsAction_not_applicable; - public static String OverrideMethodsAction_interface_not_applicable; public static String OverrideMethodsAction_annotation_not_applicable; public static String CleanUpAction_label; diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties index 91e0a2b229..f0123a6e3f 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties @@ -86,7 +86,6 @@ OverrideMethodsAction_error_actionfailed=An error occurred while creating the me OverrideMethodsAction_error_title=Override/Implement Methods OverrideMethodsAction_error_nothing_found=No methods to override found for this type. OverrideMethodsAction_not_applicable=The operation is not applicable to the current selection. Select a type. -OverrideMethodsAction_interface_not_applicable=The Override Methods operation is not applicable to interfaces. OverrideMethodsAction_annotation_not_applicable=The Override Methods operation is not applicable to annotations. AddGetterSetterAction_label=Gene&rate Getters and Setters... diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/OverrideMethodsAction.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/OverrideMethodsAction.java index 9cce445c7a..03859ffd30 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/OverrideMethodsAction.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/OverrideMethodsAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -184,11 +184,6 @@ public class OverrideMethodsAction extends SelectionDispatchAction { notifyResult(false); return; } - if (type.isInterface()) { - MessageDialog.openInformation(getShell(), getDialogTitle(), ActionMessages.OverrideMethodsAction_interface_not_applicable); - notifyResult(false); - return; - } run(getShell(), type); } else { MessageDialog.openInformation(getShell(), getDialogTitle(), ActionMessages.OverrideMethodsAction_not_applicable); |
