Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTill Brychcy2017-07-26 14:39:07 +0000
committerTill Brychcy2017-12-17 15:42:28 +0000
commit9e60b686a9f4ca3cc115c793d65d32f226f9f749 (patch)
tree66a29ff9e97ea18e416b1a5c90cbc8a8bea090f5
parent05dfe0ebf68f8d862634fcc05d3fdf4e82d1dde1 (diff)
downloadeclipse.jdt.ui-9e60b686a9f4ca3cc115c793d65d32f226f9f749.tar.gz
eclipse.jdt.ui-9e60b686a9f4ca3cc115c793d65d32f226f9f749.tar.xz
eclipse.jdt.ui-9e60b686a9f4ca3cc115c793d65d32f226f9f749.zip
Bug 528871 - [1.8][null] Avoid creating redundant @NonNull in "Anonymous
Inner Type" completion Change-Id: I42532b411a9135b261fe30bd29c6b15bcddccc6a
-rw-r--r--org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest18.java124
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java15
2 files changed, 135 insertions, 4 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 d501b941ab..f68c2f9c1f 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, 2016 GK Software AG, IBM Corporation and others.
+ * Copyright (c) 2014, 2017 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
@@ -12,6 +12,7 @@
package org.eclipse.jdt.text.tests.contentassist;
import java.util.Hashtable;
+import java.util.Map;
import org.eclipse.jdt.testplugin.JavaProjectHelper;
import org.eclipse.jdt.testplugin.TestOptions;
@@ -21,6 +22,7 @@ import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.source.ISourceViewer;
@@ -767,4 +769,124 @@ public class CodeCompletionTest18 extends AbstractCompletionTest {
buf.append("}\n");
assertEquals(buf.toString(), doc.get());
}
+ private void prepareNullAnnotations(IPackageFragmentRoot sourceFolder) throws JavaModelException {
+ Map<String, String> options= fJProject1.getOptions(true);
+ options.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+ options.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "annots.NonNull");
+ options.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "annots.Nullable");
+ options.put(JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME, "annots.NonNullByDefault");
+ fJProject1.setOptions(options);
+
+ IPackageFragment pack0= sourceFolder.createPackageFragment("annots", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package annots;\n");
+ buf.append("\n");
+ buf.append("import java.lang.annotation.*;\n");
+ buf.append("\n");
+ buf.append("@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)\n");
+ buf.append("@Target({ ElementType.TYPE_USE })\n");
+ buf.append("public @interface NonNull {}\n");
+ pack0.createCompilationUnit("NonNull.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package annots;\n");
+ buf.append("\n");
+ buf.append("import java.lang.annotation.*;\n");
+ buf.append("\n");
+ buf.append("@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)\n");
+ buf.append("@Target({ ElementType.TYPE_USE })\n");
+ buf.append("public @interface Nullable {}\n");
+ pack0.createCompilationUnit("Nullable.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package annots;\n");
+ buf.append("\n");
+ buf.append("public enum DefaultLocation { PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND, TYPE_ARGUMENT, ARRAY_CONTENTS, TYPE_PARAMETER }\n");
+ pack0.createCompilationUnit("DefaultLocation.java", buf.toString(), false, null);
+
+ buf= new StringBuffer();
+ buf.append("package annots;\n");
+ buf.append("\n");
+ buf.append("import java.lang.annotation.*;\n");
+ buf.append("import static annots.DefaultLocation.*;\n");
+ buf.append("\n");
+ buf.append("@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)\n");
+ buf.append("@Target({ ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE })\n");
+ buf.append("public @interface NonNullByDefault { DefaultLocation[] value() default {PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND, TYPE_ARGUMENT}; }\n");
+ pack0.createCompilationUnit("NonNullByDefault.java", buf.toString(), false, null);
+ }
+
+ private static void assertNumberOf(String name, int is, int expected) {
+ assertTrue("Wrong number of " + name + ", is: " + is + ", expected: " + expected, is == expected);
+ }
+
+ public void testBug528871() throws Exception {
+ IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+ prepareNullAnnotations(sourceFolder);
+
+ IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("\n");
+ buf.append("import annots.NonNull;\n");
+ buf.append("import annots.NonNullByDefault;\n");
+ buf.append("\n");
+ buf.append("interface A {\n");
+ buf.append(" @NonNull String m();\n");
+ buf.append("}\n");
+ buf.append("\n");
+ buf.append("@NonNullByDefault\n");
+ buf.append("public class Test {\n");
+ buf.append(" void f() {\n");
+ buf.append(" new A()\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("");
+ String contents= buf.toString();
+
+ ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null);
+
+ String str= "new A(";
+
+ int offset= contents.indexOf(str) + str.length();
+
+ CompletionProposalCollector collector= createCollector(cu, offset);
+ collector.setReplacementLength(0);
+
+ codeComplete(cu, offset, collector);
+
+ IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals();
+
+ assertNumberOf("proposals", proposals.length, 1);
+
+ IDocument doc= new Document(contents);
+
+ proposals[0].apply(doc);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("\n");
+ buf.append("import annots.NonNull;\n");
+ buf.append("import annots.NonNullByDefault;\n");
+ buf.append("\n");
+ buf.append("interface A {\n");
+ buf.append(" @NonNull String m();\n");
+ buf.append("}\n");
+ buf.append("\n");
+ buf.append("@NonNullByDefault\n");
+ buf.append("public class Test {\n");
+ buf.append(" void f() {\n");
+ buf.append(" new A() {\n");
+ buf.append(" \n");
+ buf.append(" @Override\n");
+ buf.append(" public String m() {\n");
+ buf.append(" //TODO\n");
+ buf.append(" return null;\n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("");
+ assertEquals(buf.toString(), doc.get());
+ }
}
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java
index 5ba5b509ac..f072901ee2 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java
@@ -57,11 +57,13 @@ import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
+import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
@@ -120,7 +122,7 @@ public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal
return buffer.toString();
}
- private String createNewBody(ImportRewrite importRewrite) throws CoreException {
+ private String createNewBody(ImportRewrite importRewrite, int offset) throws CoreException {
if (importRewrite == null)
return null;
@@ -148,12 +150,18 @@ public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal
// add an extra block: helps the AST to recover
workingCopyContents.insert(insertPosition, '{' + dummyClassContent + '}');
insertPosition++;
+ if(offset > insertPosition) {
+ offset += dummyClassContent.length()+2;
+ }
} else {
/*
* The two empty lines are added because the trackedDeclaration uses the covered range
* and hence would also included comments that directly follow the dummy class.
*/
workingCopyContents.insert(insertPosition, dummyClassContent + "\n\n"); //$NON-NLS-1$
+ if(offset > insertPosition) {
+ offset += dummyClassContent.length()+2;
+ }
}
workingCopy.getBuffer().setContents(workingCopyContents.toString());
@@ -164,6 +172,7 @@ public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal
parser.setSource(workingCopy);
CompilationUnit astRoot= (CompilationUnit) parser.createAST(new NullProgressMonitor());
+ ImportRewriteContext context=new ContextSensitiveImportRewriteContext(astRoot, offset, importRewrite);
ASTNode newType= NodeFinder.perform(astRoot, insertPosition, dummyClassContent.length());
if (!(newType instanceof AbstractTypeDeclaration))
return null;
@@ -238,7 +247,7 @@ public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal
ListRewrite rewriter= rewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty());
for (int i= 0; i < methodsToOverride.length; i++) {
IMethodBinding curr= methodsToOverride[i];
- MethodDeclaration stub= StubUtility2.createImplementationStub(workingCopy, rewrite, importRewrite, null, curr, dummyTypeBinding, settings, dummyTypeBinding.isInterface(), contextBinding);
+ MethodDeclaration stub= StubUtility2.createImplementationStub(workingCopy, rewrite, importRewrite, context, curr, dummyTypeBinding, settings, dummyTypeBinding.isInterface(), contextBinding);
rewriter.insertFirst(stub, null);
}
@@ -385,7 +394,7 @@ public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal
@Override
protected boolean updateReplacementString(IDocument document, char trigger, int offset, ImportRewrite impRewrite) throws CoreException, BadLocationException {
fImportRewrite= impRewrite;
- String newBody= createNewBody(impRewrite);
+ String newBody= createNewBody(impRewrite, offset);
if (newBody == null)
return false;

Back to the top