Bug 15589 - code assist adds extra semicolons in import type
declarations

Change-Id: Ic69d2730e0f3790d330f9d161bc7626ba116c365
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java
index 4af16e9..198b674 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -86,6 +86,7 @@
 import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProcessor;
 import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposalComputer;
 import org.eclipse.jdt.internal.ui.text.java.JavaNoTypeCompletionProposalComputer;
+import org.eclipse.jdt.internal.ui.text.java.JavaTypeCompletionProposalComputer;
 
 import junit.extensions.TestSetup;
 import junit.framework.Test;
@@ -183,6 +184,7 @@
 		store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, true);
 		store.setValue(PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS, false);
 		store.setValue(PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS, false);
+		store.setValue(PreferenceConstants.CODEASSIST_INSERT_COMPLETION, true);
 
 		StubUtility.setCodeTemplate(CodeTemplateContextType.OVERRIDECOMMENT_ID, "/* (non-Javadoc)\n * ${see_to_overridden}\n */", null);
 		StubUtility.setCodeTemplate(CodeTemplateContextType.DELEGATECOMMENT_ID, "/* (non-Javadoc)\n * ${see_to_target}\n */", null);
@@ -2325,6 +2327,127 @@
 		}
 	}
 
+	/*
+	 * Ensure no extra ';' is inserted
+	 */
+	public void testImport() throws Exception {
+		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+		IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayL; // here\n");
+		buf.append("public class A {\n");
+		buf.append("}\n");
+		String contents= buf.toString();
+		ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null);
+
+		String str= "; // here";
+		int offset= contents.indexOf(str);
+
+		IEditorPart part= JavaUI.openInEditor(cu);
+		ISourceViewer viewer= ((JavaEditor) part).getViewer();
+		JavaContentAssistInvocationContext context= new JavaContentAssistInvocationContext(viewer, offset, part);
+		JavaCompletionProposalComputer computer= new JavaTypeCompletionProposalComputer();
+
+		// make sure we get an import rewrite context
+		SharedASTProviderCore.getAST(cu, SharedASTProviderCore.WAIT_YES, null);
+
+		List<ICompletionProposal> proposals= computer.computeCompletionProposals(context, null);
+		assertEquals("Expecting 1 proposal", 1, proposals.size());
+
+		IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput());
+		proposals.get(0).apply(doc);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList; // here\n");
+		buf.append("public class A {\n");
+		buf.append("}\n");
+		assertEquals(buf.toString(), doc.get());
+	}
+
+	/*
+	 * Ensure no extra ';' is inserted, whereas a selected text part is correctly replaced
+	 */
+	public void testImportReplacingSelection() throws Exception {
+		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+		IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayLWrong;\n");
+		buf.append("public class A {\n");
+		buf.append("}\n");
+		String contents= buf.toString();
+		ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null);
+
+		IEditorPart part= JavaUI.openInEditor(cu);
+		String str= "Wrong";
+
+		int offset= contents.indexOf(str);
+
+		CompletionProposalCollector collector= createCollector(cu, offset);
+		collector.setAllowsRequiredProposals(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true);
+		collector.setReplacementLength("Wrong".length());
+
+		codeComplete(cu, offset, collector);
+		IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals();
+
+		assertEquals("expect 1 proposal", 1, proposals.length);
+
+		IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput());
+		proposals[0].apply(doc);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("public class A {\n");
+		buf.append("}\n");
+		assertEquals(buf.toString(), doc.get());
+	}
+
+	/*
+	 * Ensure no extra ';' is inserted, whereas remain text is replaced as per the preference option
+	 */
+	public void testImportReplacing() throws Exception {
+		getJDTUIPrefs().setValue(PreferenceConstants.CODEASSIST_INSERT_COMPLETION, false);
+
+		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+		IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayLWrong;\n");
+		buf.append("public class A {\n");
+		buf.append("}\n");
+		String contents= buf.toString();
+		ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null);
+
+		IEditorPart part= JavaUI.openInEditor(cu);
+		String str= "Wrong";
+
+		int offset= contents.indexOf(str);
+
+		CompletionProposalCollector collector= createCollector(cu, offset);
+		collector.setAllowsRequiredProposals(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true);
+
+		codeComplete(cu, offset, collector);
+		IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals();
+
+		assertEquals("expect 1 proposal", 1, proposals.length);
+
+		IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput());
+		proposals[0].apply(doc);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("public class A {\n");
+		buf.append("}\n");
+		assertEquals(buf.toString(), doc.get());
+	}
+
 	public void testConstructorCompletion_Bug336451() throws Exception {
 		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/FillArgumentNamesCompletionProposalCollector.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/FillArgumentNamesCompletionProposalCollector.java
index 1bb53ce..8a89dc7 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/FillArgumentNamesCompletionProposalCollector.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/FillArgumentNamesCompletionProposalCollector.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -15,6 +15,7 @@
 
 import org.eclipse.jface.preference.IPreferenceStore;
 
+import org.eclipse.jdt.core.CompletionContext;
 import org.eclipse.jdt.core.CompletionProposal;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaProject;
@@ -98,7 +99,9 @@
 
 		char[] completion= typeProposal.getCompletion();
 		// don't add parameters for import-completions nor for proposals with an empty completion (e.g. inside the type argument list)
-		if (completion.length > 0 && (completion[completion.length - 1] == ';' || completion[completion.length - 1] == '.'))
+		if (completion.length > 0 && completion[completion.length - 1] == '.')
+			return super.createJavaCompletionProposal(typeProposal);
+		if (getInvocationContext().getCoreContext().getTokenLocation() == CompletionContext.TL_IN_IMPORT)
 			return super.createJavaCompletionProposal(typeProposal);
 
 		LazyJavaCompletionProposal newProposal= new LazyGenericTypeProposal(typeProposal, getInvocationContext());