View | Details | Raw Unified | Return to bug 337977 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationQuickFixTest.java (+251 lines)
Lines 471-474 Link Here
471
		buf.append("}\n");
471
		buf.append("}\n");
472
		assertEqualString(preview, buf.toString());
472
		assertEqualString(preview, buf.toString());
473
	}
473
	}
474
475
	// @Nullable argument is used where @NonNull is required -> change to @NonNull
476
	public void testChangeParameter1() throws Exception {
477
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
478
		StringBuffer buf= new StringBuffer();
479
		buf.append("package test1;\n");
480
		buf.append("import org.eclipse.jdt.annotation.*;\n");
481
		buf.append("public class E {\n");
482
		buf.append("    @NonNull Exception e = new Exception();\n");
483
		buf.append("    void foo(@Nullable Exception e1) {\n");
484
		buf.append("        this.e = e1;\n");
485
		buf.append("    }\n");
486
		buf.append("}\n");
487
		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
488
489
		CompilationUnit astRoot= getASTRoot(cu);
490
		ArrayList proposals= collectCorrections(cu, astRoot);
491
		assertNumberOfProposals(proposals, 1);
492
		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
493
		String preview= getPreviewContent(proposal);
494
495
		buf= new StringBuffer();
496
		buf.append("package test1;\n");
497
		buf.append("import org.eclipse.jdt.annotation.*;\n");
498
		buf.append("public class E {\n");
499
		buf.append("    @NonNull Exception e = new Exception();\n");
500
		buf.append("    void foo(@NonNull Exception e1) {\n");
501
		buf.append("        this.e = e1;\n");
502
		buf.append("    }\n");
503
		buf.append("}\n");
504
		assertEqualString(preview, buf.toString());
505
	}
506
507
	// unspec'ed argument is used where @NonNull is required -> change to @NonNull
508
	public void testChangeParameter1a() throws Exception {
509
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
510
		StringBuffer buf= new StringBuffer();
511
		buf.append("package test1;\n");
512
		buf.append("import org.eclipse.jdt.annotation.*;\n");
513
		buf.append("public class E {\n");
514
		buf.append("    @NonNull Exception e = new Exception();\n");
515
		buf.append("    void foo(Exception e1) {\n");
516
		buf.append("        this.e = e1;\n");
517
		buf.append("    }\n");
518
		buf.append("}\n");
519
		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
520
521
		CompilationUnit astRoot= getASTRoot(cu);
522
		ArrayList proposals= collectCorrections(cu, astRoot);
523
		assertNumberOfProposals(proposals, 2); // other is add @SW
524
		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
525
		String preview= getPreviewContent(proposal);
526
527
		buf= new StringBuffer();
528
		buf.append("package test1;\n");
529
		buf.append("import org.eclipse.jdt.annotation.*;\n");
530
		buf.append("public class E {\n");
531
		buf.append("    @NonNull Exception e = new Exception();\n");
532
		buf.append("    void foo(@NonNull Exception e1) {\n");
533
		buf.append("        this.e = e1;\n");
534
		buf.append("    }\n");
535
		buf.append("}\n");
536
		assertEqualString(preview, buf.toString());
537
	}
538
539
	// don't propose to change argument if mismatch is in an assignment to the argument
540
	public void testChangeParameter2() throws Exception {
541
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
542
		StringBuffer buf= new StringBuffer();
543
		buf.append("package test1;\n");
544
		buf.append("import org.eclipse.jdt.annotation.*;\n");
545
		buf.append("public class E {\n");
546
		buf.append("    void foo(@NonNull Exception e1) {\n");
547
		buf.append("        e1 = null;\n");
548
		buf.append("    }\n");
549
		buf.append("}\n");
550
		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
551
552
		CompilationUnit astRoot= getASTRoot(cu);
553
		ArrayList proposals= collectCorrections(cu, astRoot);
554
		assertNumberOfProposals(proposals, 0);
555
	}
556
557
	// Attempt to override a @Nullable argument with a @NonNull argument 
558
	// -> change to @Nullable
559
	// -> change overridden to @NonNull
560
	public void testChangeParameter3() throws Exception {
561
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
562
		StringBuffer buf= new StringBuffer();
563
		buf.append("package test1;\n");
564
		buf.append("import org.eclipse.jdt.annotation.*;\n");
565
		buf.append("public class E {\n");
566
		buf.append("    void foo(@Nullable Exception e1) {\n");
567
		buf.append("    }\n");
568
		buf.append("}\n");
569
		pack1.createCompilationUnit("E.java", buf.toString(), false, null);
570
		
571
		buf= new StringBuffer();
572
		buf.append("package test1;\n");
573
		buf.append("import org.eclipse.jdt.annotation.*;\n");
574
		buf.append("public class E2 extends E {\n");
575
		buf.append("    void foo(@NonNull Exception e1) {\n");
576
		buf.append("        e1.printStackTrace();\n");
577
		buf.append("    }\n");
578
		buf.append("}\n");
579
		ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
580
581
		CompilationUnit astRoot= getASTRoot(cu);
582
		ArrayList proposals= collectCorrections(cu, astRoot);
583
		assertNumberOfProposals(proposals, 2);
584
		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
585
		String preview= getPreviewContent(proposal);
586
587
		buf= new StringBuffer();
588
		buf.append("package test1;\n");
589
		buf.append("import org.eclipse.jdt.annotation.*;\n");
590
		buf.append("public class E2 extends E {\n");
591
		buf.append("    void foo(@Nullable Exception e1) {\n"); // change override to accept @Nullable
592
		buf.append("        e1.printStackTrace();\n");
593
		buf.append("    }\n");
594
		buf.append("}\n");
595
		assertEqualString(preview, buf.toString());
596
597
		proposal= (CUCorrectionProposal) proposals.get(1);
598
		preview= getPreviewContent(proposal);
599
600
		buf= new StringBuffer();
601
		buf.append("package test1;\n");
602
		buf.append("import org.eclipse.jdt.annotation.*;\n");
603
		buf.append("public class E {\n");
604
		buf.append("    void foo(@NonNull Exception e1) {\n"); // change the overridden method to force @NonNull
605
		buf.append("    }\n");
606
		buf.append("}\n");
607
		assertEqualString(preview, buf.toString());
608
	}
609
610
	// Attempt to override a @Nullable argument with an unspec'ed argument 
611
	// -> change to @Nullable
612
	public void testChangeParameter3a() throws Exception {
613
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
614
		StringBuffer buf= new StringBuffer();
615
		buf.append("package test1;\n");
616
		buf.append("import org.eclipse.jdt.annotation.*;\n");
617
		buf.append("public class E {\n");
618
		buf.append("    void foo(@Nullable Exception e1) {\n");
619
		buf.append("    }\n");
620
		buf.append("}\n");
621
		pack1.createCompilationUnit("E.java", buf.toString(), false, null);
622
		
623
		buf= new StringBuffer();
624
		buf.append("package test1;\n");
625
		buf.append("public class E2 extends E {\n");
626
		buf.append("    void foo(Exception e1) {\n");
627
		buf.append("        e1.printStackTrace();\n");
628
		buf.append("    }\n");
629
		buf.append("}\n");
630
		ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
631
632
		CompilationUnit astRoot= getASTRoot(cu);
633
		ArrayList proposals= collectCorrections(cu, astRoot);
634
		assertNumberOfProposals(proposals, 1);
635
		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
636
		String preview= getPreviewContent(proposal);
637
638
		buf= new StringBuffer();
639
		buf.append("package test1;\n");
640
		buf.append("\n");
641
		buf.append("import org.eclipse.jdt.annotation.Nullable;\n");
642
		buf.append("\n");
643
		buf.append("public class E2 extends E {\n");
644
		buf.append("    void foo(@Nullable Exception e1) {\n"); // change override to accept @Nullable
645
		buf.append("        e1.printStackTrace();\n");
646
		buf.append("    }\n");
647
		buf.append("}\n");
648
		assertEqualString(preview, buf.toString());
649
	}
650
651
	// Attempt to override a @NonNull argument with an unspec'ed argument 
652
	// -> change to @NonNull
653
	// TODO(stephan): here the underlying error is actually debatable / not necessary.
654
	//                @NonNull -> unspec'ed could be seen as safe contravariant overriding
655
	public void testChangeParameter3b() throws Exception {
656
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
657
		StringBuffer buf= new StringBuffer();
658
		buf.append("package test1;\n");
659
		buf.append("import org.eclipse.jdt.annotation.*;\n");
660
		buf.append("public class E {\n");
661
		buf.append("    void foo(@NonNull Exception e1) {\n");
662
		buf.append("    }\n");
663
		buf.append("}\n");
664
		pack1.createCompilationUnit("E.java", buf.toString(), false, null);
665
		
666
		buf= new StringBuffer();
667
		buf.append("package test1;\n");
668
		buf.append("public class E2 extends E {\n");
669
		buf.append("    void foo(Exception e1) {\n");
670
		buf.append("        e1.printStackTrace();\n");
671
		buf.append("    }\n");
672
		buf.append("}\n");
673
		ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
674
675
		CompilationUnit astRoot= getASTRoot(cu);
676
		ArrayList proposals= collectCorrections(cu, astRoot);
677
		assertNumberOfProposals(proposals, 1);
678
		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
679
		String preview= getPreviewContent(proposal);
680
681
		buf= new StringBuffer();
682
		buf.append("package test1;\n");
683
		buf.append("\n");
684
		buf.append("import org.eclipse.jdt.annotation.NonNull;\n");
685
		buf.append("\n");
686
		buf.append("public class E2 extends E {\n");
687
		buf.append("    void foo(@NonNull Exception e1) {\n"); // change override to accept @Nullable
688
		buf.append("        e1.printStackTrace();\n");
689
		buf.append("    }\n");
690
		buf.append("}\n");
691
		assertEqualString(preview, buf.toString());
692
	}
693
694
	// returning @Nullable value from @NonNull method -> change to @Nullable return
695
	public void testChangeReturn1() throws Exception {
696
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
697
		StringBuffer buf= new StringBuffer();
698
		buf.append("package test1;\n");
699
		buf.append("import org.eclipse.jdt.annotation.*;\n");
700
		buf.append("public class E {\n");
701
		buf.append("    @Nullable Object o;\n");
702
		buf.append("    @NonNull Object foo() {\n");
703
		buf.append("        return this.o;\n");
704
		buf.append("    }\n");
705
		buf.append("}\n");
706
		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
707
708
		CompilationUnit astRoot= getASTRoot(cu);
709
		ArrayList proposals= collectCorrections(cu, astRoot);
710
		assertNumberOfProposals(proposals, 2); // other is: add @SW
711
		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
712
		String preview= getPreviewContent(proposal);
713
714
		buf= new StringBuffer();
715
		buf.append("package test1;\n");
716
		buf.append("import org.eclipse.jdt.annotation.*;\n");
717
		buf.append("public class E {\n");
718
		buf.append("    @Nullable Object o;\n");
719
		buf.append("    @Nullable Object foo() {\n");
720
		buf.append("        return this.o;\n");
721
		buf.append("    }\n");
722
		buf.append("}\n");
723
		assertEqualString(preview, buf.toString());
724
	}
474
}
725
}
(-)a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/NullQuickFixes.java (-6 / +15 lines)
Lines 67-78 Link Here
67
		CompilationUnit astRoot= context.getASTRoot();
67
		CompilationUnit astRoot= context.getASTRoot();
68
		ASTNode selectedNode= problem.getCoveringNode(astRoot);
68
		ASTNode selectedNode= problem.getCoveringNode(astRoot);
69
69
70
		if (isComplainingAboutArgument(selectedNode) || isComplainingAboutReturn(selectedNode))
70
		boolean isArgumentProblem = isComplainingAboutArgument(selectedNode);
71
			addNullAnnotationInSignatureProposal(context, problem, proposals, false);
71
		if (isArgumentProblem || isComplainingAboutReturn(selectedNode))
72
			addNullAnnotationInSignatureProposal(context, problem, proposals, false, isArgumentProblem);
72
	}
73
	}
73
74
74
	public static void addNullAnnotationInSignatureProposal(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals, boolean modifyOverridden) {
75
	public static void addNullAnnotationInSignatureProposal(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals, 
75
		MyCURewriteOperationsFix fix= createNullAnnotationInSignatureFix(context.getASTRoot(), problem, modifyOverridden);
76
			boolean modifyOverridden, boolean isArgumentProblem) 
77
	{
78
		MyCURewriteOperationsFix fix= createNullAnnotationInSignatureFix(context.getASTRoot(), problem, modifyOverridden, isArgumentProblem);
76
79
77
		if (fix != null) {
80
		if (fix != null) {
78
			Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
81
			Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
Lines 132-138 Link Here
132
		return selectedNode.getParent().getNodeType() == ASTNode.RETURN_STATEMENT;
135
		return selectedNode.getParent().getNodeType() == ASTNode.RETURN_STATEMENT;
133
	}
136
	}
134
137
135
	private static MyCURewriteOperationsFix createNullAnnotationInSignatureFix(CompilationUnit compilationUnit, IProblemLocation problem, boolean modifyOverridden) {
138
	private static MyCURewriteOperationsFix createNullAnnotationInSignatureFix(CompilationUnit compilationUnit, IProblemLocation problem, 
139
				boolean modifyOverridden, boolean isArgumentProblem) 
140
	{
136
		String nullableAnnotationName= getNullableAnnotationName(compilationUnit.getJavaElement(), false);
141
		String nullableAnnotationName= getNullableAnnotationName(compilationUnit.getJavaElement(), false);
137
		String nonNullAnnotationName= getNonNullAnnotationName(compilationUnit.getJavaElement(), false);
142
		String nonNullAnnotationName= getNonNullAnnotationName(compilationUnit.getJavaElement(), false);
138
		String annotationToAdd= nullableAnnotationName;
143
		String annotationToAdd= nullableAnnotationName;
Lines 157-163 Link Here
157
			case IProblem.RequiredNonNullButProvidedNull:
162
			case IProblem.RequiredNonNullButProvidedNull:
158
			case IProblem.RequiredNonNullButProvidedPotentialNull:
163
			case IProblem.RequiredNonNullButProvidedPotentialNull:
159
			case IProblem.RequiredNonNullButProvidedUnknown:
164
			case IProblem.RequiredNonNullButProvidedUnknown:
160
				annotationToAdd= nonNullAnnotationName;
165
			case IProblem.RequiredNonNullButProvidedSpecdNullable:
166
				if (isArgumentProblem) {
167
					annotationToAdd= nonNullAnnotationName;
168
					annotationToRemove= nullableAnnotationName;
169
				}
161
				break;
170
				break;
162
		// all others propose to add @Nullable
171
		// all others propose to add @Nullable
163
		}
172
		}
(-)a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java (-2 / +2 lines)
Lines 679-686 Link Here
679
			case IProblem.IllegalReturnNullityRedefinition:
679
			case IProblem.IllegalReturnNullityRedefinition:
680
			case IProblem.IllegalDefinitionToNonNullParameter:
680
			case IProblem.IllegalDefinitionToNonNullParameter:
681
			case IProblem.IllegalRedefinitionToNonNullParameter:
681
			case IProblem.IllegalRedefinitionToNonNullParameter:
682
				NullQuickFixes.addNullAnnotationInSignatureProposal(context, problem, proposals, false);
682
				NullQuickFixes.addNullAnnotationInSignatureProposal(context, problem, proposals, false, true);
683
				NullQuickFixes.addNullAnnotationInSignatureProposal(context, problem, proposals, true);
683
				NullQuickFixes.addNullAnnotationInSignatureProposal(context, problem, proposals, true, true);
684
				break;
684
				break;
685
			case IProblem.RequiredNonNullButProvidedNull:
685
			case IProblem.RequiredNonNullButProvidedNull:
686
			case IProblem.RequiredNonNullButProvidedPotentialNull:
686
			case IProblem.RequiredNonNullButProvidedPotentialNull:

Return to bug 337977