blob: 683cc7e9d8ffb9bfb0552e55bbad184e5e52314b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2020 GK Software AG 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:
* Stephan Herrmann - initial API and implementation
* IBM Corporation - bug fixes
*******************************************************************************/
package org.eclipse.jdt.ui.tests.quickfix;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.osgi.framework.Bundle;
import org.eclipse.jdt.testplugin.JavaProjectHelper;
import org.eclipse.jdt.testplugin.TestOptions;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IEditorInput;
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.manipulation.CodeTemplateContextType;
import org.eclipse.jdt.internal.core.manipulation.StubUtility;
import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring.MultiFixTarget;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jdt.ui.text.java.IProblemLocation;
import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
import org.eclipse.jdt.internal.ui.text.correction.CorrectionMarkerResolutionGenerator;
import org.eclipse.jdt.internal.ui.text.correction.CorrectionMarkerResolutionGenerator.CorrectionMarkerResolution;
import org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor;
import org.eclipse.jdt.internal.ui.text.correction.proposals.CreatePackageInfoWithDefaultNullnessProposal;
@RunWith(JUnit4.class)
public class NullAnnotationsQuickFixTest extends QuickFixTest {
@Rule
public ProjectTestSetup projectSetup = new ProjectTestSetup();
private IJavaProject fJProject1;
private IPackageFragmentRoot fSourceFolder;
private String ANNOTATION_JAR_PATH;
@Before
public void setUp() throws Exception {
Hashtable<String, String> options= TestOptions.getDefaultOptions();
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));
options.put(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER, JavaCore.ERROR);
options.put(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION, JavaCore.IGNORE);
options.put(JavaCore.COMPILER_PB_MISSING_HASHCODE_METHOD, JavaCore.WARNING);
options.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
options.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION, JavaCore.ERROR);
options.put(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR);
options.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.WARNING);
options.put(JavaCore.COMPILER_PB_NULL_ANNOTATION_INFERENCE_CONFLICT, JavaCore.WARNING);
options.put(JavaCore.COMPILER_PB_NULL_UNCHECKED_CONVERSION, JavaCore.WARNING);
options.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.WARNING);
options.put(JavaCore.COMPILER_PB_NULL_UNCHECKED_CONVERSION, JavaCore.WARNING);
JavaCore.setOptions(options);
IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, false);
StubUtility.setCodeTemplate(CodeTemplateContextType.CATCHBLOCK_ID, "", null);
StubUtility.setCodeTemplate(CodeTemplateContextType.CONSTRUCTORSTUB_ID, "", null);
StubUtility.setCodeTemplate(CodeTemplateContextType.METHODSTUB_ID, "", null);
fJProject1= projectSetup.getProject();
if (ANNOTATION_JAR_PATH == null) {
String version= "[1.1.0,2.0.0)"; // tests run at 1.5, need the "old" null annotations
Bundle[] bundles= Platform.getBundles("org.eclipse.jdt.annotation", version);
File bundleFile= FileLocator.getBundleFile(bundles[0]);
if (bundleFile.isDirectory())
ANNOTATION_JAR_PATH= bundleFile.getPath() + "/bin";
else
ANNOTATION_JAR_PATH= bundleFile.getPath();
}
JavaProjectHelper.addLibrary(fJProject1, new Path(ANNOTATION_JAR_PATH));
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
}
@After
public void tearDown() throws Exception {
JavaProjectHelper.clear(fJProject1, projectSetup.getDefaultClasspath());
}
// ==== Problem: dereferencing a @Nullable field
// ==== Fix: extract field access to a fresh local variable and add a null-check
// basic case
@Test
public void testExtractNullableField1() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo() {\n");
buf.append(" System.out.println(f.toUpperCase());\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo() {\n");
buf.append(" final String f2 = f;\n");
buf.append(" if (f2 != null) {\n");
buf.append(" System.out.println(f2.toUpperCase());\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// statement is not element of a block - need to create a new block - local name f2 already in use
@Test
public void testExtractNullableField2() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo(boolean b) {\n");
buf.append(" @SuppressWarnings(\"unused\") boolean f2 = false;\n");
buf.append(" if (b)\n");
buf.append(" System.out.println(f.toUpperCase());\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo(boolean b) {\n");
buf.append(" @SuppressWarnings(\"unused\") boolean f2 = false;\n");
buf.append(" if (b) {\n");
buf.append(" final String f3 = f;\n");
buf.append(" if (f3 != null) {\n");
buf.append(" System.out.println(f3.toUpperCase());\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// field name is part of a qualified field reference - inside a return statement (type: int)
@Test
public void testExtractNullableField3() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable E other;\n");
buf.append(" int f;\n");
buf.append(" public int foo(E that) {\n");
buf.append(" return that.other.f;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable E other;\n");
buf.append(" int f;\n");
buf.append(" public int foo(E that) {\n");
buf.append(" final E other2 = that.other;\n");
buf.append(" if (other2 != null) {\n");
buf.append(" return other2.f;\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" return 0;\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// field name is part of a this-qualified field reference - inside a return statement (type: String)
@Test
public void testExtractNullableField4() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable E other;\n");
buf.append(" @Nullable String f;\n");
buf.append(" public String foo() {\n");
buf.append(" return this.other.f;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable E other;\n");
buf.append(" @Nullable String f;\n");
buf.append(" public String foo() {\n");
buf.append(" final E other2 = this.other;\n");
buf.append(" if (other2 != null) {\n");
buf.append(" return other2.f;\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" return null;\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// field referenced inside the rhs of an assignment-as-expression
@Test
public void testExtractNullableField5() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable E other;\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo() {\n");
buf.append(" String lo;\n");
buf.append(" if ((lo = this.other.f) != null)\n");
buf.append(" System.out.println(lo);\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable E other;\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo() {\n");
buf.append(" String lo;\n");
buf.append(" final E other2 = this.other;\n");
buf.append(" if (other2 != null) {\n");
buf.append(" if ((lo = other2.f) != null)\n");
buf.append(" System.out.println(lo);\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// reference to field of array type - dereferenced by f[0] and f.length
@Test
public void testExtractNullableField6() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String[] f1;\n");
buf.append(" @Nullable String[] f2;\n");
buf.append(" public void foo() {\n");
buf.append(" System.out.println(f1[0]);\n");
buf.append(" System.out.println(f2.length);\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 2, 0); // get correction for first of two problems
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String[] f1;\n");
buf.append(" @Nullable String[] f2;\n");
buf.append(" public void foo() {\n");
buf.append(" final String[] f12 = f1;\n");
buf.append(" if (f12 != null) {\n");
buf.append(" System.out.println(f12[0]);\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" System.out.println(f2.length);\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposals= collectCorrections(cu, astRoot, 2, 1); // get correction for second of two problems
assertNumberOfProposals(proposals, 3);
proposal= (CUCorrectionProposal) proposals.get(0);
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String[] f1;\n");
buf.append(" @Nullable String[] f2;\n");
buf.append(" public void foo() {\n");
buf.append(" System.out.println(f1[0]);\n");
buf.append(" final String[] f22 = f2;\n");
buf.append(" if (f22 != null) {\n");
buf.append(" System.out.println(f22.length);\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// field has a generic type
@Test
public void testExtractNullableField7() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("import java.util.List;\n");
buf.append("public class E {\n");
buf.append(" @Nullable List<String> f;\n");
buf.append(" public void foo() {\n");
buf.append(" System.out.println(f.size());\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("import java.util.List;\n");
buf.append("public class E {\n");
buf.append(" @Nullable List<String> f;\n");
buf.append(" public void foo() {\n");
buf.append(" final List<String> f2 = f;\n");
buf.append(" if (f2 != null) {\n");
buf.append(" System.out.println(f2.size());\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// occurrences inside a class initializer
@Test
public void testExtractNullableField8() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable Exception e;\n");
buf.append(" {\n");
buf.append(" e.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable Exception e;\n");
buf.append(" {\n");
buf.append(" final Exception e2 = e;\n");
buf.append(" if (e2 != null) {\n");
buf.append(" e2.printStackTrace();\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// field reference inside a local variable initialization - ensure correct scoping of this local
@Test
public void testExtractNullableField9() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public String foo() {\n");
buf.append(" String upper = f.toUpperCase();\n");
buf.append(" System.out.println(upper);\n");
buf.append(" return upper;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 4);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public String foo() {\n");
buf.append(" final String f2 = f;\n");
buf.append(" if (f2 != null) {\n");
buf.append(" String upper = f2.toUpperCase();\n");
buf.append(" System.out.println(upper);\n");
buf.append(" return upper;\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// ==== Problem: using a @Nullable or un-annotated field in assignment/return context expecting @NonNull
// ==== Fix: extract field access to a fresh local variable and add a null-check
// return situation, field reference is this.f
@Test
public void testExtractPotentiallyNullField1() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public @NonNull String foo() {\n");
buf.append(" return this.f;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
// primary proposal: Extract to checked local variable
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public @NonNull String foo() {\n");
buf.append(" final String f2 = this.f;\n");
buf.append(" if (f2 != null) {\n");
buf.append(" return f2;\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" return null;\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
// secondary proposal: Change return type of 'foo(..)' to '@Nullable'
proposal= (CUCorrectionProposal) proposals.get(1);
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public @Nullable String foo() {\n");
buf.append(" return this.f;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// message send argument situation, field reference is local.f
@Test
public void testExtractPotentiallyNullField2() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo() {\n");
buf.append(" E local = this;\n");
buf.append(" bar(local.f);\n");
buf.append(" }\n");
buf.append(" public void bar(@NonNull String s) { }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable String f;\n");
buf.append(" public void foo() {\n");
buf.append(" E local = this;\n");
buf.append(" final String f2 = local.f;\n");
buf.append(" if (f2 != null) {\n");
buf.append(" bar(f2);\n");
buf.append(" } else {\n");
buf.append(" // TODO handle null value\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append(" public void bar(@NonNull String s) { }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// @Nullable argument is used where @NonNull is required -> change to @NonNull
@Test
public void testChangeParameter1a() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Exception e1) {\n");
buf.append(" @NonNull Exception e = new Exception();\n");
buf.append(" e = e1;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'e1' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Exception e1) {\n");
buf.append(" @NonNull Exception e = new Exception();\n");
buf.append(" e = e1;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// unspec'ed argument is used where @NonNull is required -> change to @NonNull
@Test
public void testChangeParameter1b() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(Exception e1) {\n");
buf.append(" @NonNull Exception e = new Exception();\n");
buf.append(" e = e1;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3); // other is add @SW - TODO: check when this is offered
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'e1' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Exception e1) {\n");
buf.append(" @NonNull Exception e = new Exception();\n");
buf.append(" e = e1;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testChangeParameter1c() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo(@Nullable Object o) {\n");
buf.append(" return o;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'o' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo(@NonNull Object o) {\n");
buf.append(" return o;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testChangeParameter1d() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo(Object o) {\n");
buf.append(" return o;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.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 'o' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo(@NonNull Object o) {\n");
buf.append(" return o;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// don't propose to change argument if mismatch is in an assignment to the argument
@Test
public void testChangeParameter2() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Exception e1) {\n");
buf.append(" e1 = null;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 1);
}
// Attempt to override a @Nullable argument with a @NonNull argument
// -> change to @Nullable
// -> change overridden to @NonNull
@Test
public void testChangeParameter3a() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Exception e1) {\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(@NonNull Exception e1) {\n");
buf.append(" e1.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 'e1' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(@Nullable Exception e1) {\n"); // change override to accept @Nullable
buf.append(" e1.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change parameter in overridden 'foo(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Exception e1) {\n"); // change the overridden method to force @NonNull
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// Attempt to override a @Nullable argument with an unspec'ed argument
// -> change to @Nullable
@Test
public void testChangeParameter3b() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Exception e1) {\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(Exception e1) {\n");
buf.append(" e1.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'e1' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.Nullable;\n");
buf.append("\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(@Nullable Exception e1) {\n"); // change override to accept @Nullable
buf.append(" e1.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// Attempt to override a @NonNull argument with an unspec'ed argument
// -> change to @NonNull
@Test
public void testChangeParameter3c() throws Exception {
// quickfix only offered with this warning enabled, but no need to say, because default is already "warning"
// this.fJProject1.setOption(JavaCore.COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED, JavaCore.WARNING);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Exception e1) {\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(Exception e1) {\n");
buf.append(" e1.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 4); // one real change plus two @SuppressWarnings proposals
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'e1' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.NonNull;\n");
buf.append("\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(@NonNull Exception e1) {\n"); // change override to keep @NonNull
buf.append(" e1.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// http://bugs.eclipse.org/400668 - [quick fix] The fix change parameter type to @Nonnull generated a null change
// don't confuse changing arguments of current method and target method
// -> split into two proposals
@Test
public void testChangeParameter4() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Object o) {\n");
buf.append(" // nop\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 {\n");
buf.append(" void test(E e, @Nullable Object in) {\n");
buf.append(" e.foo(in);\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 'in' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 {\n");
buf.append(" void test(E e, @NonNull Object in) {\n");
buf.append(" e.foo(in);\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change parameter of 'foo(..)' to '@Nullable'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Object o) {\n");
buf.append(" // nop\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// http://bugs.eclipse.org/400668 - [quick fix] The fix change parameter type to @Nonnull generated a null change
// don't confuse changing arguments of current method and target method
// -> split into two proposals
// variant with un-annotated parameter
@Test
public void testChangeParameter4a() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Object o) {\n");
buf.append(" // nop\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E2 {\n");
buf.append(" void test(E e, Object in) {\n");
buf.append(" e.foo(in);\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 4); // third (uninteresting) is "add @SW"
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'in' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.NonNull;\n");
buf.append("\n");
buf.append("public class E2 {\n");
buf.append(" void test(E e, @NonNull Object in) {\n");
buf.append(" e.foo(in);\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change parameter of 'foo(..)' to '@Nullable'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Object o) {\n");
buf.append(" // nop\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// Bug 405086 - [quick fix] don't propose null annotations when those are disabled
@Test
public void testChangeParameter5() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.DISABLED);
try {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E {\n");
buf.append(" void foo(Object o) {\n");
buf.append(" if (o == null) return;\n");
buf.append(" if (o != null) System.out.print(o.toString());\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2); // only "add @SW"
} finally {
fJProject1.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
}
}
// Bug 405086 - [quick fix] don't propose null annotations when those are disabled
// don't propose a parameter change if there was no parameter annotation being the cause for the warning
@Test
public void testChangeParameter6() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E {\n");
buf.append(" void foo(Object o) {\n");
buf.append(" if (o == null) return;\n");
buf.append(" if (o != null) System.out.print(o.toString());\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2); // only "add @SW"
}
// Bug 405086 - [quick fix] don't propose null annotations when those are disabled
// positive case (redundant check)
@Test
public void testChangeParameter7() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Object o) {\n");
buf.append(" if (o != null) System.out.print(o.toString());\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3); // ignore 2nd ("add @SW")
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'o' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Object o) {\n");
buf.append(" if (o != null) System.out.print(o.toString());\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// Bug 405086 - [quick fix] don't propose null annotations when those are disabled
// positive case 2 (check always false)
@Test
public void testChangeParameter8() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E {\n");
buf.append(" void foo(@org.eclipse.jdt.annotation.NonNull Object o) {\n");
buf.append(" if (o == null) System.out.print(\"NOK\");\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3); // ignore 2nd ("add @SW")
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change parameter 'o' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.Nullable;\n");
buf.append("\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Object o) {\n");
buf.append(" if (o == null) System.out.print(\"NOK\");\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// http://bugs.eclipse.org/395555 - [quickfix] Update null annotation quick fixes for bug 388281
// conflict between inherited and default nullness
@Test
public void testChangeParameter9() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_INHERIT_NULL_ANNOTATIONS, JavaCore.ENABLED);
try {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@Nullable Object o) {\n");
buf.append(" // nop\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(Object o) {\n");
buf.append(" System.out.print(\"E2\");\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 'o' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(@Nullable Object o) {\n");
buf.append(" System.out.print(\"E2\");\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change parameter in overridden 'foo(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Object o) {\n");
buf.append(" // nop\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_INHERIT_NULL_ANNOTATIONS, JavaCore.DISABLED);
}
}
// returning @Nullable value from @NonNull method -> change to @Nullable return
@Test
public void testChangeReturn1() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo() {\n");
buf.append(" @Nullable Object o = null;\n");
buf.append(" return o;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable Object foo() {\n");
buf.append(" @Nullable Object o = null;\n");
buf.append(" return o;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testChangeReturn2a() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 extends E {\n");
buf.append(" @Nullable Object foo() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 return type of 'foo(..)' to '@NonNull'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 extends E {\n");
buf.append(" @NonNull Object foo() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change return type of overridden 'foo(..)' to '@Nullable'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable Object foo() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testChangeReturn2b() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E2 extends E {\n");
buf.append(" Object foo() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.NonNull;\n");
buf.append("\n");
buf.append("public class E2 extends E {\n");
buf.append(" @NonNull\n");
buf.append(" Object foo() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// https://bugs.eclipse.org/395555 - [quickfix] Update null annotation quick fixes for bug 388281
// conflict between nullness inherited from different parents
@Test
public void testChangeReturn3() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_INHERIT_NULL_ANNOTATIONS, JavaCore.ENABLED);
try {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object foo() {\n");
buf.append(" // nop\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public interface IE {\n");
buf.append(" @Nullable Object foo();\n");
buf.append("}\n");
pack1.createCompilationUnit("IE.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E2 extends E implements IE {\n");
buf.append(" public Object foo() {\n");
buf.append(" return this;\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 return type of 'foo(..)' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.Nullable;\n");
buf.append("\n");
buf.append("public class E2 extends E implements IE {\n");
buf.append(" public @Nullable Object foo() {\n");
buf.append(" return this;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change return type of 'foo(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.NonNull;\n");
buf.append("\n");
buf.append("public class E2 extends E implements IE {\n");
buf.append(" public @NonNull Object foo() {\n");
buf.append(" return this;\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_INHERIT_NULL_ANNOTATIONS, JavaCore.DISABLED);
}
}
// https://bugs.eclipse.org/378724 - Null annotations are extremely hard to use in an existing project
// see comment 12
// remove @Nullable without adding redundant @NonNull (due to @NonNullByDefault)
@Test
public void testChangeReturn4() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" @Nullable Object bar() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 {\n");
buf.append(" @NonNull Object foo(E e) {\n");
buf.append(" return e.bar();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 return type of 'foo(..)' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 {\n");
buf.append(" @Nullable Object foo(E e) {\n");
buf.append(" return e.bar();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change return type of 'bar(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" Object bar() {\n"); // here's the rub: don't add redundant @NonNull, just remove @Nullable
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// https://bugs.eclipse.org/378724 - Null annotations are extremely hard to use in an existing project
// see comment 12
// remove @Nullable without adding redundant @NonNull (due to @NonNullByDefault)
// variant: package-level default
@Test
public void testChangeReturn5() throws Exception {
String suppressOptionalErrors= fJProject1.getOption(JavaCore.COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS, true);
try {
fJProject1.setOption(JavaCore.COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS, JavaCore.ENABLED);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
buf.append("package test1;\n");
pack1.createCompilationUnit("package-info.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @Nullable Object bar() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E2 {\n");
buf.append(" public Object foo(E e) {\n"); // non-null by default
buf.append(" return e.bar();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 4); // includes "add @SW"
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Change return type of 'foo(..)' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.Nullable;\n");
buf.append("\n");
buf.append("public class E2 {\n");
buf.append(" public @Nullable Object foo(E e) {\n");
buf.append(" return e.bar();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change return type of 'bar(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" Object bar() {\n"); // here's the rub: don't add redundant @NonNull, just remove @Nullable
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS, suppressOptionalErrors);
}
}
// https://bugs.eclipse.org/378724 - Null annotations are extremely hard to use in an existing project
// see comment 12
// remove @Nullable without adding redundant @NonNull (due to @NonNullByDefault)
// variant: cancelled default
@Test
public void testChangeReturn6() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
buf.append("package test1;\n");
pack1.createCompilationUnit("package-info.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault(false)\n"); // <- HERE
buf.append("public class E {\n");
buf.append(" @Nullable Object bar() {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E2 {\n");
buf.append(" public Object foo(E e) {\n"); // non-null by default
buf.append(" return e.bar();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 return type of 'foo(..)' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.Nullable;\n");
buf.append("\n");
buf.append("public class E2 {\n");
buf.append(" public @Nullable Object foo(E e) {\n");
buf.append(" return e.bar();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change return type of 'bar(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault(false)\n");
buf.append("public class E {\n");
buf.append(" @NonNull Object bar() {\n"); // here's the rub: DO add redundant @NonNull, default is cancelled here
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation1() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" void foo(@NonNull Object o) {\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 4);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" void foo(Object o) {\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation2() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" @NonNull\n");
buf.append(" Object foo(Object o) {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" Object foo(Object o) {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation3() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" @NonNull\n");
buf.append(" public Object foo(Object o) {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" public Object foo(Object o) {\n");
buf.append(" return new Object();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation4() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" @NonNullByDefault\n");
buf.append(" void foo(Object o) {\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" void foo(Object o) {\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation5() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" @NonNullByDefault\n");
buf.append(" class E1 {\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append(" class E1 {\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation6() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNullByDefault\n");
buf.append(" void foo(Object o) {\n");
buf.append(" @NonNullByDefault\n");
buf.append(" class E1 {\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNullByDefault\n");
buf.append(" void foo(Object o) {\n");
buf.append(" class E1 {\n");
buf.append(" }\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation7() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
buf.append("package test1;\n");
pack1.createCompilationUnit("package-info.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("@NonNullByDefault\n");
buf.append("public class E {\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testRemoveRedundantAnnotation8() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
buf.append("package test1;\n");
pack1.createCompilationUnit("package-info.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" @NonNullByDefault\n");
buf.append(" void foo(Object o) {\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(Object o) {\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testAddNonNull() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class E {\n");
buf.append(" public <T extends Number> double foo(boolean b) {\n");
buf.append(" Number n=Integer.valueOf(1);\n");
buf.append(" if(b) {\n");
buf.append(" n = null;\n");
buf.append(" };\n");
buf.append(" return n.doubleValue();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import org.eclipse.jdt.annotation.NonNull;\n");
buf.append("\n");
buf.append("public class E {\n");
buf.append(" public <T extends Number> double foo(boolean b) {\n");
buf.append(" @NonNull\n");
buf.append(" Number n=Integer.valueOf(1);\n");
buf.append(" if(b) {\n");
buf.append(" n = null;\n");
buf.append(" };\n");
buf.append(" return n.doubleValue();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
// Attempt to override an unspec'ed argument with a @NonNull argument
// -> change to @Nullable
// -> change overridden to @NonNull
// Specific for this test: arg name is different in overridden method.
@Test
public void testBug506108() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(Exception e, Exception e1, Exception e2) {\n");
buf.append(" }\n");
buf.append("}\n");
pack1.createCompilationUnit("E.java", buf.toString(), false, null);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(Exception e1, @NonNull Exception e2, Exception e) {\n");
buf.append(" e2.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E2.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 'e2' to '@Nullable'");
String preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E2 extends E {\n");
buf.append(" void foo(Exception e1, @Nullable Exception e2, Exception e) {\n"); // change override to accept @Nullable
buf.append(" e2.printStackTrace();\n");
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
proposal= (CUCorrectionProposal)proposals.get(1);
assertEqualString(proposal.getDisplayString(), "Change parameter in overridden 'foo(..)' to '@NonNull'");
preview= getPreviewContent(proposal);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("import org.eclipse.jdt.annotation.*;\n");
buf.append("public class E {\n");
buf.append(" void foo(Exception e, @NonNull Exception e1, Exception e2) {\n"); // change the overridden method to force @NonNull
buf.append(" }\n");
buf.append("}\n");
assertEqualString(preview, buf.toString());
}
@Test
public void testBug525428a() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);
try {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
ICompilationUnit cu= pack1.createCompilationUnit("package-info.java", buf.toString(), false, null);
CompilationUnit astRoot= getASTRoot(cu);
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot);
assertNumberOfProposals(proposals, 2);
CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Add '@NonNullByDefault' to the package declaration");
String preview= getPreviewContent(proposal);
buf= new StringBuilder();
buf.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
buf.append("package test1;\n");
assertEqualStringIgnoreDelim(preview, buf.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.IGNORE);
}
}
@Test
public void testBug525428b() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);
String typecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, null).getPattern();
String filecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, null).getPattern();
try {
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, "/**\n * Type\n */", null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, "/**\n * File\n */", null);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E {\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
cu.getJavaProject().getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
IMarker[] markers= pack1.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertEquals(1, markers.length);
ArrayList<IJavaCompletionProposal> proposals= new ArrayList<>();
IInvocationContext context= new AssistContext(cu, 0, 0);
IEditorInput input= EditorUtility.getEditorInput(cu);
IProblemLocation location= CorrectionMarkerResolutionGenerator.findProblemLocation(input, markers[0]);
IStatus status= JavaCorrectionProcessor.collectCorrections(context, new IProblemLocation[] { location }, proposals);
assertStatusOk(status);
assertNumberOfProposals(proposals, 2);
IJavaCompletionProposal proposal= proposals.get(0);
assertEqualString(proposal.getDisplayString(), "Add package-info.java with '@NonNullByDefault'");
proposal.apply(null);
cu.getJavaProject().getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
assertEquals(0, pack1.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE).length);
ICompilationUnit packageInfoCU= pack1.getCompilationUnit("package-info.java");
StringBuilder expected=new StringBuilder();
expected.append("/**\n");
expected.append(" * File\n");
expected.append(" */\n");
expected.append("/**\n");
expected.append(" * Type\n");
expected.append(" */\n");
expected.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
expected.append("package test1;\n");
assertEqualStringIgnoreDelim(packageInfoCU.getSource(), expected.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.IGNORE);
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, typecomment, null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, filecomment, null);
}
}
// marker for same project in two source folders in same project: package-info.java must be created in first one (when comparing paths)
@Test
public void testBug525428c() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);
String typecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, null).getPattern();
String filecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, null).getPattern();
try {
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, "/**\n * Type\n */", null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, "/**\n * File\n */", null);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E {\n");
buf.append("}\n");
ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
IPackageFragmentRoot testSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src-tests");
IPackageFragment pack2= testSourceFolder.createPackageFragment("test1", false, null);
cu.getJavaProject().getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
buf=new StringBuilder();
buf.append("package test1;\n");
buf.append("public class ETest {\n");
buf.append("}\n");
ICompilationUnit cu2= pack2.createCompilationUnit("ETest.java", buf.toString(), false, null);
// after the incremental, there is also a problem marker on the package in the src-tests directory
cu2.getJavaProject().getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
IMarker[] markers= pack1.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertEquals(1, markers.length);
IMarker[] markers2= pack2.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertEquals(1, markers2.length);
ArrayList<IJavaCompletionProposal> proposals= new ArrayList<>();
IInvocationContext context= new AssistContext(cu, 0, 0);
IEditorInput input= EditorUtility.getEditorInput(cu);
IProblemLocation location= CorrectionMarkerResolutionGenerator.findProblemLocation(input, markers[0]);
IStatus status= JavaCorrectionProcessor.collectCorrections(context, new IProblemLocation[] { location }, proposals);
assertStatusOk(status);
IInvocationContext context2= new AssistContext(cu, 0, 0);
IEditorInput input2= EditorUtility.getEditorInput(cu);
IProblemLocation location2= CorrectionMarkerResolutionGenerator.findProblemLocation(input2, markers2[0]);
status= JavaCorrectionProcessor.collectCorrections(context2, new IProblemLocation[] { location2 }, proposals);
assertStatusOk(status);
assertNumberOfProposals(proposals, 4);
IJavaCompletionProposal proposal= proposals.get(0);
IJavaCompletionProposal proposal2= proposals.get(2);
assertEqualString(proposal.getDisplayString(), "Add package-info.java with '@NonNullByDefault'");
assertEqualString(proposal2.getDisplayString(), "Add package-info.java with '@NonNullByDefault'");
MultiFixTarget[] problems= CorrectionMarkerResolution.getCleanUpTargets(new IMarker[] { markers[0], markers2[0] });
((CreatePackageInfoWithDefaultNullnessProposal) proposal).resolve(problems, new NullProgressMonitor());
cu.getJavaProject().getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
assertEquals(0, cu.getJavaProject().getProject().findMarkers(null, true, IResource.DEPTH_INFINITE).length);
ICompilationUnit packageInfoCU= pack1.getCompilationUnit("package-info.java");
ICompilationUnit packageInfoCU2= pack2.getCompilationUnit("package-info.java");
assertTrue("a package-info.java should have been created in src", packageInfoCU.exists());
assertFalse("no package-info.java should have been created in src-tests", packageInfoCU2.exists());
StringBuilder expected= new StringBuilder();
expected.append("/**\n");
expected.append(" * File\n");
expected.append(" */\n");
expected.append("/**\n");
expected.append(" * Type\n");
expected.append(" */\n");
expected.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
expected.append("package test1;\n");
assertEqualStringIgnoreDelim(packageInfoCU.getSource(), expected.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.IGNORE);
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, typecomment, null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, filecomment, null);
}
}
// marker for same project in two dependent projects: package-info.java must be created in the one that cannot see the other
@Test
public void testBug525428d() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);
String typecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, null).getPattern();
String filecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, null).getPattern();
IJavaProject proj2=null;
try {
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, "/**\n * Type\n */", null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, "/**\n * File\n */", null);
proj2= JavaProjectHelper.createJavaProject("OtherProject", "bin");
proj2.setRawClasspath(projectSetup.getDefaultClasspath(), null);
TestOptions.initializeProjectOptions(proj2);
JavaProjectHelper.addLibrary(proj2, new Path(ANNOTATION_JAR_PATH));
JavaProjectHelper.addRequiredProject(proj2, fJProject1);
IPackageFragmentRoot sourceFolder2= JavaProjectHelper.addSourceContainer(proj2, "src");
proj2.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E1 {\n");
buf.append("}\n");
ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null);
IPackageFragment pack2= sourceFolder2.createPackageFragment("test1", false, null);
buf=new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E2 {\n");
buf.append("}\n");
ICompilationUnit cu2= pack2.createCompilationUnit("E2.java", buf.toString(), false, null);
cu2.getJavaProject().getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
IMarker[] markers= pack1.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertEquals(1, markers.length);
IMarker[] markers2= pack2.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertEquals(1, markers2.length);
ArrayList<IJavaCompletionProposal> proposals= new ArrayList<>();
IInvocationContext context= new AssistContext(cu1, 0, 0);
IEditorInput input= EditorUtility.getEditorInput(cu1);
IProblemLocation location= CorrectionMarkerResolutionGenerator.findProblemLocation(input, markers[0]);
IStatus status= JavaCorrectionProcessor.collectCorrections(context, new IProblemLocation[] { location }, proposals);
assertStatusOk(status);
IInvocationContext context2= new AssistContext(cu2, 0, 0);
IEditorInput input2= EditorUtility.getEditorInput(cu2);
IProblemLocation location2= CorrectionMarkerResolutionGenerator.findProblemLocation(input2, markers2[0]);
status= JavaCorrectionProcessor.collectCorrections(context2, new IProblemLocation[] { location2 }, proposals);
assertStatusOk(status);
assertNumberOfProposals(proposals, 4);
IJavaCompletionProposal proposal= proposals.get(0);
IJavaCompletionProposal proposal2= proposals.get(2);
assertEqualString(proposal.getDisplayString(), "Add package-info.java with '@NonNullByDefault'");
assertEqualString(proposal2.getDisplayString(), "Add package-info.java with '@NonNullByDefault'");
MultiFixTarget[] problems= CorrectionMarkerResolution.getCleanUpTargets(new IMarker[] { markers[0], markers2[0] });
((CreatePackageInfoWithDefaultNullnessProposal) proposal).resolve(problems, new NullProgressMonitor());
cu1.getJavaProject().getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
assertEquals(0, cu1.getJavaProject().getProject().findMarkers(null, true, IResource.DEPTH_INFINITE).length);
assertEquals(0, cu2.getJavaProject().getProject().findMarkers(null, true, IResource.DEPTH_INFINITE).length);
ICompilationUnit packageInfoCU= pack1.getCompilationUnit("package-info.java");
ICompilationUnit packageInfoCU2= pack2.getCompilationUnit("package-info.java");
assertTrue("a package-info.java should have been created in fJProject1", packageInfoCU.exists());
assertFalse("no package-info.java should have been created in proj2", packageInfoCU2.exists());
StringBuilder expected= new StringBuilder();
expected.append("/**\n");
expected.append(" * File\n");
expected.append(" */\n");
expected.append("/**\n");
expected.append(" * Type\n");
expected.append(" */\n");
expected.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
expected.append("package test1;\n");
assertEqualStringIgnoreDelim(packageInfoCU.getSource(), expected.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.IGNORE);
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, typecomment, null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, filecomment, null);
if (proj2 != null) {
JavaProjectHelper.delete(proj2);
}
}
}
// marker for same project in two independent projects: package-info.java must be created in both
@Test
public void testBug525428e() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);
String typecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, null).getPattern();
String filecomment= StubUtility.getCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, null).getPattern();
IJavaProject proj2=null;
try {
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, "/**\n * Type\n */", null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, "/**\n * File\n */", null);
proj2= JavaProjectHelper.createJavaProject("OtherProject", "bin");
proj2.setRawClasspath(projectSetup.getDefaultClasspath(), null);
TestOptions.initializeProjectOptions(proj2);
JavaProjectHelper.addLibrary(proj2, new Path(ANNOTATION_JAR_PATH));
IPackageFragmentRoot sourceFolder2= JavaProjectHelper.addSourceContainer(proj2, "src");
proj2.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf= new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E1 {\n");
buf.append("}\n");
ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", buf.toString(), false, null);
IPackageFragment pack2= sourceFolder2.createPackageFragment("test1", false, null);
buf=new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E2 {\n");
buf.append("}\n");
ICompilationUnit cu2= pack2.createCompilationUnit("E2.java", buf.toString(), false, null);
cu2.getJavaProject().getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
IMarker[] markers= pack1.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertEquals(1, markers.length);
IMarker[] markers2= pack2.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertEquals(1, markers2.length);
ArrayList<IJavaCompletionProposal> proposals= new ArrayList<>();
IInvocationContext context= new AssistContext(cu1, 0, 0);
IEditorInput input= EditorUtility.getEditorInput(cu1);
IProblemLocation location= CorrectionMarkerResolutionGenerator.findProblemLocation(input, markers[0]);
IStatus status= JavaCorrectionProcessor.collectCorrections(context, new IProblemLocation[] { location }, proposals);
assertStatusOk(status);
IInvocationContext context2= new AssistContext(cu2, 0, 0);
IEditorInput input2= EditorUtility.getEditorInput(cu2);
IProblemLocation location2= CorrectionMarkerResolutionGenerator.findProblemLocation(input2, markers2[0]);
status= JavaCorrectionProcessor.collectCorrections(context2, new IProblemLocation[] { location2 }, proposals);
assertStatusOk(status);
assertNumberOfProposals(proposals, 4);
IJavaCompletionProposal proposal= proposals.get(0);
IJavaCompletionProposal proposal2= proposals.get(2);
assertEqualString(proposal.getDisplayString(), "Add package-info.java with '@NonNullByDefault'");
assertEqualString(proposal2.getDisplayString(), "Add package-info.java with '@NonNullByDefault'");
MultiFixTarget[] problems= CorrectionMarkerResolution.getCleanUpTargets(new IMarker[] { markers[0], markers2[0] });
((CreatePackageInfoWithDefaultNullnessProposal) proposal).resolve(problems, new NullProgressMonitor());
cu1.getJavaProject().getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
assertEquals(0, cu1.getJavaProject().getProject().findMarkers(null, true, IResource.DEPTH_INFINITE).length);
assertEquals(0, cu2.getJavaProject().getProject().findMarkers(null, true, IResource.DEPTH_INFINITE).length);
ICompilationUnit packageInfoCU= pack1.getCompilationUnit("package-info.java");
ICompilationUnit packageInfoCU2= pack2.getCompilationUnit("package-info.java");
assertTrue("a package-info.java should have been created in fJProject1", packageInfoCU.exists());
assertTrue("a package-info.java should have been created in proj2", packageInfoCU2.exists());
StringBuilder expected= new StringBuilder();
expected.append("/**\n");
expected.append(" * File\n");
expected.append(" */\n");
expected.append("/**\n");
expected.append(" * Type\n");
expected.append(" */\n");
expected.append("@org.eclipse.jdt.annotation.NonNullByDefault\n");
expected.append("package test1;\n");
assertEqualStringIgnoreDelim(packageInfoCU.getSource(), expected.toString());
} finally {
fJProject1.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.IGNORE);
StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, typecomment, null);
StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, filecomment, null);
if (proj2 != null) {
JavaProjectHelper.delete(proj2);
}
}
}
}