blob: b38631466a208055705dd475946df83b44a55504 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2016 GK Software AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stephan Herrmann - initial API and implementation
* IBM Corporation - bug fixes
*******************************************************************************/
package org.eclipse.jdt.ui.tests.quickfix;
import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;
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.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
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.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.tests.core.ProjectTestSetup;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import junit.framework.Test;
import junit.framework.TestSuite;
public class NullAnnotationsQuickFixTest extends QuickFixTest {
private static final Class<NullAnnotationsQuickFixTest> THIS= NullAnnotationsQuickFixTest.class;
private IJavaProject fJProject1;
private IPackageFragmentRoot fSourceFolder;
private String ANNOTATION_JAR_PATH;
public NullAnnotationsQuickFixTest(String name) {
super(name);
}
public static Test suite() {
return setUpTest(new TestSuite(THIS));
}
public static Test setUpTest(Test test) {
return new ProjectTestSetup(test);
}
@Override
protected 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= ProjectTestSetup.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");
}
@Override
protected void tearDown() throws Exception {
JavaProjectHelper.clear(fJProject1, ProjectTestSetup.getDefaultClasspath());
}
// ==== Problem: dereferencing a @Nullable field
// ==== Fix: extract field access to a fresh local variable and add a null-check
// basic case
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, 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(" 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
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, 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(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)
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, 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 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)
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, 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 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
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, 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 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
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, 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[] 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, 2);
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
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, 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("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
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, 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 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
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, 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 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
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
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
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
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());
}
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());
}
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
public void testChangeParameter2() 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 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
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
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
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
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
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
public void testChangeParameter5() throws Exception {
fJProject1.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.DISABLED);
try {
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(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
public void testChangeParameter6() 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(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)
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)
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
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
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());
}
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());
}
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
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)
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
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
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());
}
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());
}
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());
}
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());
}
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());
}
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());
}
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());
}
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());
}
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());
}
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.
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());
}
}