blob: be74c508db149bafd969f282da750a910c37f46c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Till Brychcy - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ui.tests.quickfix;
import java.util.ArrayList;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.eclipse.jdt.testplugin.JavaProjectHelper;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.internal.core.ClasspathAttribute;
import org.eclipse.jdt.ui.tests.core.rules.Java9ProjectTestSetup;
import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal;
public class NullAnnotationsQuickFixTest9 extends QuickFixTest {
@Rule
public ProjectTestSetup projectSetup = new Java9ProjectTestSetup();
private IJavaProject fJProject1;
private IJavaProject fJProject2;
private IPackageFragmentRoot fSourceFolder;
@Before
public void setUp() throws CoreException {
fJProject2= JavaProjectHelper.createJavaProject("annots", "bin");
JavaProjectHelper.set9CompilerOptions(fJProject2);
JavaProjectHelper.addRTJar9(fJProject2);
IPackageFragmentRoot java9Src= JavaProjectHelper.addSourceContainer(fJProject2, "src");
IPackageFragment def= java9Src.createPackageFragment("", false, null);
StringBuffer buf= new StringBuffer();
buf.append("module annots {\n");
buf.append(" exports annots; \n");
buf.append("}\n");
def.createCompilationUnit("module-info.java", buf.toString(), false, null);
IPackageFragment annots= java9Src.createPackageFragment("annots", false, null);
buf= new StringBuffer();
buf.append("package annots;\n");
buf.append("\n");
buf.append("import java.lang.annotation.ElementType;\n");
buf.append("import java.lang.annotation.Target;\n");
buf.append("\n");
buf.append("@Target(ElementType.TYPE_USE)\n");
buf.append("public @interface Nullable {\n");
buf.append("}\n");
annots.createCompilationUnit("Nullable.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package annots;\n");
buf.append("\n");
buf.append("import java.lang.annotation.ElementType;\n");
buf.append("import java.lang.annotation.Target;\n");
buf.append("\n");
buf.append("@Target(ElementType.TYPE_USE)\n");
buf.append("public @interface NonNull {\n");
buf.append("}\n");
annots.createCompilationUnit("NonNull.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package annots;\n");
buf.append("\n");
buf.append("public enum DefaultLocation {\n");
buf.append(" PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND, TYPE_ARGUMENT\n");
buf.append("}\n");
buf.append("");
annots.createCompilationUnit("DefaultLocation.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package annots;\n");
buf.append("\n");
buf.append("import static annots.DefaultLocation.*;\n");
buf.append("\n");
buf.append("public @interface NonNullByDefault {\n");
buf.append(" DefaultLocation[] value() default { PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND, TYPE_ARGUMENT };\n");
buf.append("}\n");
buf.append("");
annots.createCompilationUnit("NonNullByDefault.java", buf.toString(), false, null);
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
JavaProjectHelper.set9CompilerOptions(fJProject1);
JavaProjectHelper.addRTJar9(fJProject1);
Map<String, String> options= fJProject1.getOptions(false);
options.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
options.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "annots.Nullable");
options.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "annots.NonNull");
options.put(JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME, "annots.NonNullByDefault");
options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, String.valueOf(99));
fJProject1.setOptions(options);
IClasspathAttribute[] attributes= { new ClasspathAttribute(IClasspathAttribute.MODULE, "true") };
IClasspathEntry cpe= JavaCore.newProjectEntry(fJProject2.getProject().getFullPath(), null, false, attributes, false);
JavaProjectHelper.addToClasspath(fJProject1, cpe);
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
}
@After
public void tearDown() throws Exception {
if (fJProject1 != null) {
JavaProjectHelper.delete(fJProject1);
}
if (fJProject2 != null) {
JavaProjectHelper.delete(fJProject2);
}
}
@Test
public void testBug530580a() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("@annots.NonNullByDefault module test {\n");
buf.append(" requires annots;");
buf.append("}\n");
IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
def.createCompilationUnit("module-info.java", buf.toString(), false, null);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import java.util.Map;\n");
buf.append("import annots.*;\n");
buf.append("\n");
buf.append("abstract class Test {\n");
buf.append(" abstract Map<? extends Map<String, @Nullable Integer>, String[][]> f();\n");
buf.append("\n");
buf.append(" public void g() {\n");
buf.append(" x=f();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("Test.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 4);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Create field 'x'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import java.util.Map;\n");
buf.append("import annots.*;\n");
buf.append("\n");
buf.append("abstract class Test {\n");
buf.append(" private Map<? extends Map<String, @Nullable Integer>, String[][]> x;\n");
buf.append("\n");
buf.append(" abstract Map<? extends Map<String, @Nullable Integer>, String[][]> f();\n");
buf.append("\n");
buf.append(" public void g() {\n");
buf.append(" x=f();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Create parameter 'x'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import java.util.Map;\n");
buf.append("import annots.*;\n");
buf.append("\n");
buf.append("abstract class Test {\n");
buf.append(" abstract Map<? extends Map<String, @Nullable Integer>, String[][]> f();\n");
buf.append("\n");
buf.append(" public void g(Map<? extends Map<String, @Nullable Integer>, String[][]> x) {\n");
buf.append(" x=f();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(2);
assertEqualString(proposal.getDisplayString(), "Create local variable 'x'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import java.util.Map;\n");
buf.append("import annots.*;\n");
buf.append("\n");
buf.append("abstract class Test {\n");
buf.append(" abstract Map<? extends Map<String, @Nullable Integer>, String[][]> f();\n");
buf.append("\n");
buf.append(" public void g() {\n");
buf.append(" Map<? extends Map<String, @Nullable Integer>, String[][]> x = f();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testBug530580b() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("@annots.NonNullByDefault module test {\n");
buf.append(" requires annots;");
buf.append("}\n");
IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
def.createCompilationUnit("module-info.java", buf.toString(), false, null);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import annots.*;\n");
buf.append("\n");
buf.append("interface Type {\n");
buf.append(" void set(@Nullable String s);\n");
buf.append("\n");
buf.append(" class U implements Type {\n");
buf.append(" @Override\n");
buf.append(" public void set(String t) {\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("Test.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 't' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import annots.*;\n");
buf.append("\n");
buf.append("interface Type {\n");
buf.append(" void set(@Nullable String s);\n");
buf.append("\n");
buf.append(" class U implements Type {\n");
buf.append(" @Override\n");
buf.append(" public void set(@Nullable String t) {\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change parameter in overridden 'set(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import annots.*;\n");
buf.append("\n");
buf.append("interface Type {\n");
buf.append(" void set(String s);\n");
buf.append("\n");
buf.append(" class U implements Type {\n");
buf.append(" @Override\n");
buf.append(" public void set(String t) {\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}}