From ed8e47feb25b970ffaa715167bb0de188a71ec61 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Tue, 25 Jun 2024 10:15:48 -0400 Subject: [PATCH 1/8] Don't erase the type on the receiver --- .../org/checkerframework/common/basetype/BaseTypeVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java index 0987bbe2e59..e26bf4c17e1 100644 --- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java +++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java @@ -3772,7 +3772,7 @@ protected void checkMethodInvocability( return; } - AnnotatedTypeMirror methodReceiver = method.getReceiverType().getErased(); + AnnotatedTypeMirror methodReceiver = method.getReceiverType(); AnnotatedTypeMirror treeReceiver = methodReceiver.shallowCopy(false); AnnotatedTypeMirror rcv = atypeFactory.getReceiverType(tree); From 0df34f679a6f0563f7d49cd6da4a965fff4d812f Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 26 Jun 2024 19:32:36 -0400 Subject: [PATCH 2/8] Add jtreg test case --- .../jtreg/nullness/type-argument/TypeArgument.java | 14 ++++++++++++++ .../jtreg/nullness/type-argument/TypeArgument.out | 4 ++++ 2 files changed, 18 insertions(+) create mode 100644 checker/jtreg/nullness/type-argument/TypeArgument.java create mode 100644 checker/jtreg/nullness/type-argument/TypeArgument.out diff --git a/checker/jtreg/nullness/type-argument/TypeArgument.java b/checker/jtreg/nullness/type-argument/TypeArgument.java new file mode 100644 index 00000000000..e5d404bcac0 --- /dev/null +++ b/checker/jtreg/nullness/type-argument/TypeArgument.java @@ -0,0 +1,14 @@ +/* + * @test + * @summary Test case for type argument in method invocation. + * + * @compile/fail/ref=TypeArgument.out -XDrawDiagnostics -processor org.checkerframework.checker.nullness.NullnessChecker TypeArgument.java + */ +public class TypeArgument { + + TypeArgument() { + foo(); + } + + void foo() {} +} diff --git a/checker/jtreg/nullness/type-argument/TypeArgument.out b/checker/jtreg/nullness/type-argument/TypeArgument.out new file mode 100644 index 00000000000..86c481e3be0 --- /dev/null +++ b/checker/jtreg/nullness/type-argument/TypeArgument.out @@ -0,0 +1,4 @@ +TypeArgument.java:10:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. +found : @UnderInitialization(TypeArgument.class) TypeArgument +required: @Initialized TypeArgument +1 error From 82c9faa2ac8ac5abb8761f9cf3367be417d26336 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 26 Jun 2024 21:54:52 -0400 Subject: [PATCH 3/8] Empty commit for CI From e160b61d4c79107f7d4fef53a8b340a3a34a8a0f Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Thu, 27 Jun 2024 14:47:00 -0400 Subject: [PATCH 4/8] Delete extra folder and rename the file --- checker/jtreg/nullness/NonRawTypeArgumentTest.java | 14 ++++++++++++++ checker/jtreg/nullness/NonRawTypeArgumentTest.out | 4 ++++ .../jtreg/nullness/type-argument/TypeArgument.java | 14 -------------- .../jtreg/nullness/type-argument/TypeArgument.out | 4 ---- 4 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 checker/jtreg/nullness/NonRawTypeArgumentTest.java create mode 100644 checker/jtreg/nullness/NonRawTypeArgumentTest.out delete mode 100644 checker/jtreg/nullness/type-argument/TypeArgument.java delete mode 100644 checker/jtreg/nullness/type-argument/TypeArgument.out diff --git a/checker/jtreg/nullness/NonRawTypeArgumentTest.java b/checker/jtreg/nullness/NonRawTypeArgumentTest.java new file mode 100644 index 00000000000..0b2c62aacf7 --- /dev/null +++ b/checker/jtreg/nullness/NonRawTypeArgumentTest.java @@ -0,0 +1,14 @@ +/* + * @test + * @summary Test case for type argument in method invocation. + * + * @compile/fail/ref=NonRawTypeArgumentTest.out -XDrawDiagnostics -processor org.checkerframework.checker.nullness.NullnessChecker NonRawTypeArgumentTest.java + */ +public class NonRawTypeArgumentTest { + + NonRawTypeArgumentTest() { + foo(); + } + + void foo() {} +} diff --git a/checker/jtreg/nullness/NonRawTypeArgumentTest.out b/checker/jtreg/nullness/NonRawTypeArgumentTest.out new file mode 100644 index 00000000000..dca0ea22a9a --- /dev/null +++ b/checker/jtreg/nullness/NonRawTypeArgumentTest.out @@ -0,0 +1,4 @@ +NonRawTypeArgumentTest.java:10:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. +found : @UnderInitialization(NonRawTypeArgumentTest.class) NonRawTypeArgumentTest +required: @Initialized NonRawTypeArgumentTest +1 error diff --git a/checker/jtreg/nullness/type-argument/TypeArgument.java b/checker/jtreg/nullness/type-argument/TypeArgument.java deleted file mode 100644 index e5d404bcac0..00000000000 --- a/checker/jtreg/nullness/type-argument/TypeArgument.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * @test - * @summary Test case for type argument in method invocation. - * - * @compile/fail/ref=TypeArgument.out -XDrawDiagnostics -processor org.checkerframework.checker.nullness.NullnessChecker TypeArgument.java - */ -public class TypeArgument { - - TypeArgument() { - foo(); - } - - void foo() {} -} diff --git a/checker/jtreg/nullness/type-argument/TypeArgument.out b/checker/jtreg/nullness/type-argument/TypeArgument.out deleted file mode 100644 index 86c481e3be0..00000000000 --- a/checker/jtreg/nullness/type-argument/TypeArgument.out +++ /dev/null @@ -1,4 +0,0 @@ -TypeArgument.java:10:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. -found : @UnderInitialization(TypeArgument.class) TypeArgument -required: @Initialized TypeArgument -1 error From a5d1fada674266bb62e184c9d4123595b6bf54b5 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 3 Jul 2024 14:25:58 -0400 Subject: [PATCH 5/8] Rename the test file and refine the summary --- .../MethodReceiverTypeErrorMessageTest.java | 14 ++++++++++++++ .../MethodReceiverTypeErrorMessageTest.out | 4 ++++ checker/jtreg/nullness/NonRawTypeArgumentTest.java | 14 -------------- checker/jtreg/nullness/NonRawTypeArgumentTest.out | 4 ---- 4 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java create mode 100644 checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out delete mode 100644 checker/jtreg/nullness/NonRawTypeArgumentTest.java delete mode 100644 checker/jtreg/nullness/NonRawTypeArgumentTest.out diff --git a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java new file mode 100644 index 00000000000..31b686c0b26 --- /dev/null +++ b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java @@ -0,0 +1,14 @@ +/* + * @test + * @summary Test case for method receiver type in error message. If it is a non-raw type, it should be printed as such. + * + * @compile/fail/ref=MethodReceiverTypeErrorMessageTest.out -XDrawDiagnostics -processor org.checkerframework.checker.nullness.NullnessChecker MethodReceiverTypeErrorMessageTest.java + */ +public class MethodReceiverTypeErrorMessageTest { + + MethodReceiverTypeErrorMessageTest() { + foo(); + } + + void foo() {} +} diff --git a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out new file mode 100644 index 00000000000..2552739c584 --- /dev/null +++ b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out @@ -0,0 +1,4 @@ +MethodReceiverTypeErrorMessageTest.java:10:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. +found : @UnderInitialization(MethodReceiverTypeErrorMessageTest.class) MethodReceiverTypeErrorMessageTest +required: @Initialized MethodReceiverTypeErrorMessageTest +1 error diff --git a/checker/jtreg/nullness/NonRawTypeArgumentTest.java b/checker/jtreg/nullness/NonRawTypeArgumentTest.java deleted file mode 100644 index 0b2c62aacf7..00000000000 --- a/checker/jtreg/nullness/NonRawTypeArgumentTest.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * @test - * @summary Test case for type argument in method invocation. - * - * @compile/fail/ref=NonRawTypeArgumentTest.out -XDrawDiagnostics -processor org.checkerframework.checker.nullness.NullnessChecker NonRawTypeArgumentTest.java - */ -public class NonRawTypeArgumentTest { - - NonRawTypeArgumentTest() { - foo(); - } - - void foo() {} -} diff --git a/checker/jtreg/nullness/NonRawTypeArgumentTest.out b/checker/jtreg/nullness/NonRawTypeArgumentTest.out deleted file mode 100644 index dca0ea22a9a..00000000000 --- a/checker/jtreg/nullness/NonRawTypeArgumentTest.out +++ /dev/null @@ -1,4 +0,0 @@ -NonRawTypeArgumentTest.java:10:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. -found : @UnderInitialization(NonRawTypeArgumentTest.class) NonRawTypeArgumentTest -required: @Initialized NonRawTypeArgumentTest -1 error From b7f576751599676d4ff55c0c4f592585e9db2f2a Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Thu, 4 Jul 2024 17:10:58 -0400 Subject: [PATCH 6/8] Subclass receiver test --- .../jtreg/nullness/MethodReceiverTypeErrorMessageTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java index 31b686c0b26..bdadce69135 100644 --- a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java +++ b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java @@ -12,3 +12,9 @@ public class MethodReceiverTypeErrorMessageTest { void foo() {} } + +class sub extends MethodReceiverTypeErrorMessageTest { + sub() { + foo(); + } +} From f66d93da32ac488498aa02e4d2353c7e515c0200 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 18 Dec 2024 01:59:21 -0500 Subject: [PATCH 7/8] Also fixes 104 --- checker/tests/nullness/ReceiverTypeArgs.java | 19 +++++++++++++++++++ .../common/basetype/BaseTypeVisitor.java | 10 +++++----- .../checkerframework/javacutil/TreeUtils.java | 2 +- 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 checker/tests/nullness/ReceiverTypeArgs.java diff --git a/checker/tests/nullness/ReceiverTypeArgs.java b/checker/tests/nullness/ReceiverTypeArgs.java new file mode 100644 index 00000000000..796ee301592 --- /dev/null +++ b/checker/tests/nullness/ReceiverTypeArgs.java @@ -0,0 +1,19 @@ +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +public class ReceiverTypeArgs { + static class Box { + T item; + + public Box(T item) { + this.item = item; + } + + void test(Box<@NonNull T> this) {} + } + + private static void foo(Box<@Nullable String> box) { + // :: error: (method.invocation.invalid) + box.test(); + } +} diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java index c37df7424e1..9853b0c35ab 100644 --- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java +++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java @@ -3772,8 +3772,8 @@ protected void checkMethodInvocability( return; } - AnnotatedTypeMirror methodReceiver = method.getReceiverType(); - AnnotatedTypeMirror treeReceiver = methodReceiver.shallowCopy(false); + AnnotatedDeclaredType methodReceiver = method.getReceiverType(); + AnnotatedDeclaredType treeReceiver = methodReceiver.shallowCopy(false); AnnotatedTypeMirror rcv = atypeFactory.getReceiverType(tree); treeReceiver.addAnnotations(rcv.getEffectiveAnnotations()); @@ -3782,10 +3782,10 @@ protected void checkMethodInvocability( // The diagnostic can be a bit misleading because the check is of the receiver but // `tree` is the entire method invocation (where the receiver might be implicit). commonAssignmentCheckStartDiagnostic(methodReceiver, treeReceiver, tree); - boolean success = typeHierarchy.isSubtype(treeReceiver, methodReceiver); - commonAssignmentCheckEndDiagnostic(success, null, methodReceiver, treeReceiver, tree); + boolean success = typeHierarchy.isSubtype(rcv, methodReceiver); + commonAssignmentCheckEndDiagnostic(success, null, methodReceiver, rcv, tree); if (!success) { - reportMethodInvocabilityError(tree, treeReceiver, methodReceiver); + reportMethodInvocabilityError(tree, rcv, methodReceiver); } } } diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index 6ee85e6f2ff..ab00e87c4a5 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -251,7 +251,7 @@ public static boolean isSelfAccess(ExpressionTree tree) { * @param tree an expression tree * @return the outermost non-parenthesized tree enclosed by the given tree */ - @SuppressWarnings("interning:return.type.incompatible") // pol ymorphism implementation + @SuppressWarnings("interning:return.type.incompatible") // polymorphism implementation public static @PolyInterned ExpressionTree withoutParens(@PolyInterned ExpressionTree tree) { ExpressionTree t = tree; while (t.getKind() == Tree.Kind.PARENTHESIZED) { From 714b75a5528a14031c49b5cb83745c589d22c8cc Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 18 Dec 2024 02:08:42 -0500 Subject: [PATCH 8/8] Update expected output --- .../jtreg/nullness/MethodReceiverTypeErrorMessageTest.out | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out index 2552739c584..8ebbd6ab47d 100644 --- a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out +++ b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out @@ -1,4 +1,7 @@ MethodReceiverTypeErrorMessageTest.java:10:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. found : @UnderInitialization(MethodReceiverTypeErrorMessageTest.class) MethodReceiverTypeErrorMessageTest required: @Initialized MethodReceiverTypeErrorMessageTest -1 error +MethodReceiverTypeErrorMessageTest.java:18:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. +found : @UnderInitialization(sub.class) sub +required: @Initialized MethodReceiverTypeErrorMessageTest<@Initialized String> +2 errors