/******************************************************************************* * Copyright (c) 2015 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 *******************************************************************************/ package org.eclipse.jdt.ui.tests.quickfix; import java.io.ByteArrayInputStream; import java.util.List; import org.eclipse.core.runtime.Path; import org.eclipse.core.resources.IFile; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.ui.tests.core.Java18ProjectTestSetup; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; import junit.framework.Test; import junit.framework.TestSuite; public class AnnotateAssistTest18 extends AbstractAnnotateAssistTests { protected static final String ANNOTATION_PATH= "annots"; protected static final Class<?> THIS= AnnotateAssistTest18.class; public static Test suite() { return setUpTest(new TestSuite(THIS)); } public static Test setUpTest(Test test) { return new Java18ProjectTestSetup(test); } public AnnotateAssistTest18(String name) { super(name); } @Override protected void setUp() throws Exception { fJProject1= Java18ProjectTestSetup.getProject(); fJProject1.getProject().getFolder(ANNOTATION_PATH).create(true, true, null); fJProject1.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); } /** * Assert two proposals ("@NonNull" and "@Nullable") on a type argument of a parameter. * The parameterized type already has a @NonNull annotation. * Apply the second proposal and check the effect. * @throws Exception multiple causes */ public void testAnnotateParameter_TypeArgument() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(int[] ints, List<String> list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n" + " ([ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([IL1java/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("String> list"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as '@NonNull String'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>([ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([IL1java/util/List<L<b>1</b>java/lang/String;>;)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as '@Nullable String'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>([ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([IL1java/util/List<L<b>0</b>java/lang/String;>;)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " ([ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([IL1java/util/List<L0java/lang/String;>;)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert NO proposals on the primitive leaf type of an array type. * @throws Exception multiple causes */ public void testAnnotateParameter_ArrayOfPrimitive() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(int[] ints, List<String> list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("int[]"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertNumberOfProposals(list, 0); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on a wildcard bound inside a parameter type * The parameterized type and the wildcard already has a @NonNull annotation. * Annotation entry already exists, with @NonNull on the wildcard itself. * Apply the second proposal and check the effect. * @throws Exception multiple causes */ public void testAnnotateParameter_WildcardBound() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(Object[] objects, List<? extends Number> list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n" + " ([Ljava/lang/Object;Ljava/util/List<+Ljava/lang/Number;>;)Ljava/lang/String;\n" + " ([Ljava/lang/Object;L1java/util/List<+1Ljava/lang/Number;>;)Ljava/lang/String;\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("Number> list"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as '@NonNull Number'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>([Ljava/lang/Object;Ljava/util/List<+Ljava/lang/Number;>;)Ljava/lang/String;</dd>" + "<dd>([Ljava/lang/Object;L1java/util/List<+1L<b>1</b>java/lang/Number;>;)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as '@Nullable Number'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>([Ljava/lang/Object;Ljava/util/List<+Ljava/lang/Number;>;)Ljava/lang/String;</dd>" + "<dd>([Ljava/lang/Object;L1java/util/List<+1L<b>0</b>java/lang/Number;>;)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " ([Ljava/lang/Object;Ljava/util/List<+Ljava/lang/Number;>;)Ljava/lang/String;\n" + " ([Ljava/lang/Object;L1java/util/List<+1L0java/lang/Number;>;)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on an inner array type (in parameter position). * A single line entry using this selector exists and will be amended. * Apply the second proposal and check the effect. * * Cf. {@link AnnotateAssistTest15#testAnnotateParameter_Array1()} * @throws Exception multiple causes */ public void testAnnotateParameter_Array2() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(int[][] ints, List<String> list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("[] ints"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as 'int[] @NonNull []'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([[<b>1</b>ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as 'int[] @Nullable []'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([[<b>0</b>ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " ([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([[0ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on an inner array type (in parameter position). * An entry with annotation on the outer array already exists and will be amended. * Apply the second proposal and check the effect. * * Cf. {@link AnnotateAssistTest15#testAnnotateParameter_Array1()} * @throws Exception multiple causes */ public void testAnnotateParameter_Array3() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(int[][] ints, List<String> list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n" + " ([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([1[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("[] ints"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as 'int[] @NonNull []'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([1[<b>1</b>ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as 'int[] @Nullable []'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([1[<b>0</b>ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " ([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([1[0ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on an inner array type - extra dimensions (in parameter position). * An entry with annotation on the outer array already exists and will be amended. * Apply the second proposal and check the effect. * * Cf. {@link AnnotateAssistTest18#testAnnotateParameter_Array3()} * @throws Exception multiple causes */ public void testAnnotateParameter_Array4() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(int ints[][], List<String> list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n" + " ([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([1[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("[],"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as 'int[] @NonNull []'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([1[<b>1</b>ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as 'int[] @Nullable []'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([1[<b>0</b>ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " ([[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([1[0ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on an outer array type - extra dimensions (in parameter position). * An entry with annotation on the inner array already exists and will be amended. * Apply the second proposal and check the effect. * * Cf. {@link AnnotateAssistTest18#testAnnotateParameter_Array3()} * @throws Exception multiple causes */ public void testAnnotateParameter_Array5() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(int ints[][][], List<String> list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n" + " ([[[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([[1[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("[][][],"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as 'int @NonNull [][][]'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>([[[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([<b>1</b>[1[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as 'int @Nullable [][][]'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>([[[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + "<dd>([<b>0</b>[1[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " ([[[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n" + " ([0[1[ILjava/util/List<Ljava/lang/String;>;)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on the array representing the varargs ellipsis * Apply the second proposal and check the effect. * * Cf. {@link AnnotateAssistTest18#testAnnotateParameter_Array3()} * @throws Exception multiple causes */ public void testAnnotateParameter_Varargs1() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(List<String> list, int ... ints);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n" + " (Ljava/util/List<Ljava/lang/String;>;[I)Ljava/lang/String;\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("..."); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as 'int @NonNull ...'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[I)Ljava/lang/String;</dd>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[<b>1</b>I)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as 'int @Nullable ...'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[I)Ljava/lang/String;</dd>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[<b>0</b>I)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " (Ljava/util/List<Ljava/lang/String;>;[I)Ljava/lang/String;\n" + " (Ljava/util/List<Ljava/lang/String;>;[0I)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on the array representing the varargs ellipsis * An entry with annotation on the inner array already exists and will be amended. * Apply the second proposal and check the effect. * * Cf. {@link AnnotateAssistTest18#testAnnotateParameter_Varargs1()} * @throws Exception multiple causes */ public void testAnnotateParameter_Varargs2() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public String test(List<String> list, int[] ... ints);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); String initialContent= "class pack/age/X\n" + "test\n" + " (Ljava/util/List<Ljava/lang/String;>;[[I)Ljava/lang/String;\n" + " (Ljava/util/List<Ljava/lang/String;>;[[1I)Ljava/lang/String;\n"; ensureExists(annotationFile.getParent()); annotationFile.create(new ByteArrayInputStream(initialContent.getBytes("UTF-8")), 0, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("..."); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as 'int[] @NonNull ...'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[[I)Ljava/lang/String;</dd>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[<b>1</b>[1I)Ljava/lang/String;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as 'int[] @Nullable ...'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[[I)Ljava/lang/String;</dd>" + "<dd>(Ljava/util/List<Ljava/lang/String;>;[<b>0</b>[1I)Ljava/lang/String;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " (Ljava/util/List<Ljava/lang/String;>;[[I)Ljava/lang/String;\n" + " (Ljava/util/List<Ljava/lang/String;>;[0[1I)Ljava/lang/String;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on a method's type parameter * The parameterized type and the wildcard already has a @NonNull annotation. * Annotation entry already exists, with @NonNull on the wildcard itself. * Apply the second proposal and check the effect. * @throws Exception multiple causes */ // FIXME(stephan): enable once implemented public void _testAnnotateParameter_TypeParameter() throws Exception { String X_PATH= "pack/age/X"; String[] pathAndContents= new String[] { X_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public interface X {\n" + " public <X, T extends List<X>> X test(T list);\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_8, null); IType type= fJProject1.findType(X_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("T extends"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as '@NonNull T'", list); String expectedInfo= "<dl><dt>test</dt>" + "<dd><X:Ljava/lang/Object;T:Ljava/util/List<TX;>>(TT;)TX;</dd>" + "<dd><X:Ljava/lang/Object;1T:Ljava/util/List<TX;>>(TT;)TX;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as '@Nullable Number'", list); expectedInfo= "<dl><dt>test</dt>" + "<dd><X:Ljava/lang/Object;T:Ljava/util/List<TX;>>(TT;)TX;</dd>" + "<dd><X:Ljava/lang/Object;0T:Ljava/util/List<TX;>>(TT;)TX;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(X_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/X\n" + "test\n" + " <X:Ljava/lang/Object;T:Ljava/util/List<;TX;>>(TT;)TX;\n" + " <X:Ljava/lang/Object;0T:Ljava/util/List<;TX;>>(TT;)TX;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } /** * Assert two proposals ("@NonNull" and "@Nullable") on a complex field type (list of array) * Apply the second proposal and check the effect. * @throws Exception multiple causes */ public void testAnnotateField1() throws Exception { String NODE_PATH= "pack/age/Node"; String[] pathAndContents= new String[] { NODE_PATH+".java", "package pack.age;\n" + "import java.util.List;\n" + "public class Node {\n" + " List<Object[]> value;\n" + "}\n" }; addLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, ANNOTATION_PATH, JavaCore.VERSION_1_5, null); IType type= fJProject1.findType(NODE_PATH.replace('/', '.')); JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); try { int offset= pathAndContents[1].indexOf("[]> value"); List<ICompletionProposal> list= collectAnnotateProposals(javaEditor, offset); assertCorrectLabels(list); assertNumberOfProposals(list, 2); ICompletionProposal proposal= findProposalByName("Annotate as 'Object @NonNull []'", list); String expectedInfo= "<dl><dt>value</dt>" + "<dd>Ljava/util/List<[Ljava/lang/Object;>;</dd>" + "<dd>Ljava/util/List<[<b>1</b>Ljava/lang/Object;>;</dd>" + // <= 1 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); proposal= findProposalByName("Annotate as 'Object @Nullable []'", list); expectedInfo= "<dl><dt>value</dt>" + "<dd>Ljava/util/List<[Ljava/lang/Object;>;</dd>" + "<dd>Ljava/util/List<[<b>0</b>Ljava/lang/Object;>;</dd>" + // <= 0 "</dl>"; assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); proposal.apply(document); IFile annotationFile= fJProject1.getProject().getFile(new Path(ANNOTATION_PATH).append(NODE_PATH+".eea")); assertTrue("Annotation file should have been created", annotationFile.exists()); String expectedContent= "class pack/age/Node\n" + "value\n" + " Ljava/util/List<[Ljava/lang/Object;>;\n" + " Ljava/util/List<[0Ljava/lang/Object;>;\n"; checkContentOfFile("annotation file content", annotationFile, expectedContent); } finally { JavaPlugin.getActivePage().closeAllEditors(false); } } }