Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSpecify generics checks for conditional expressions #739

Merged
Merged
Show file tree
Hide file tree
Changes from 245 commits
Commits
Show all changes
246 commits
Select commit Hold shift + click to select a range
f306db2
an initial test case
msridhar Sep 13, 2022
16654f7
sample code
msridhar Sep 27, 2022
7f9418b
add-generics-checks
NikitaAware Sep 29, 2022
441ab7c
first-case-of-generics-support
NikitaAware Sep 30, 2022
4a9c86d
first-case-of-generics-support
NikitaAware Sep 30, 2022
01377b6
restore bad deletion
msridhar Sep 30, 2022
359dcc8
add-generics-spport-task-1-updates
NikitaAware Sep 30, 2022
731bf3d
add-generics-spport-task-1-updates
NikitaAware Sep 30, 2022
b9b8239
add-generics-spport-task-1-updates
NikitaAware Sep 30, 2022
fb1beb9
add generics check for variables
NikitaAware Oct 2, 2022
1a23f8e
Merge branch 'master' into add-generics-checks
msridhar Oct 3, 2022
90d471d
tweak error message
msridhar Oct 3, 2022
98f7fa6
more tests
msridhar Oct 3, 2022
53ddad7
code cleanup.remove print statements
NikitaAware Oct 3, 2022
7daa52b
Add temporary check to consider unannoted base type
NikitaAware Oct 3, 2022
cd01ff9
minor code changes
NikitaAware Oct 4, 2022
202d5db
add generics check for new class - check if the class is generic
NikitaAware Oct 6, 2022
3998949
add generics check for new class - check for the type arguments
NikitaAware Oct 7, 2022
fc8b99f
generics check for new class
NikitaAware Oct 10, 2022
6425909
generics check for extended class
NikitaAware Oct 10, 2022
bae84dc
generics check for new class
NikitaAware Oct 10, 2022
4aba42c
generics check for new class - minor changes for error message
NikitaAware Oct 10, 2022
bca4f24
generics check for interface implementation
NikitaAware Oct 10, 2022
99e8bf9
minor identation changes
NikitaAware Oct 10, 2022
a0caac8
nullability checks for build failures
NikitaAware Oct 11, 2022
5b9d918
Add Test: generics check for subclasses
NikitaAware Oct 11, 2022
4cb51d9
restructure generics tests
NikitaAware Oct 11, 2022
2e4a2ef
restructure generics tests
NikitaAware Oct 11, 2022
b1668e9
Add tests
NikitaAware Oct 11, 2022
9c8b3ae
restructure code
NikitaAware Oct 11, 2022
97e088b
restructure code
NikitaAware Oct 11, 2022
036febf
restructure code
NikitaAware Oct 11, 2022
f065bd9
Merge branch 'master' into add-generics-checks
msridhar Oct 11, 2022
00ad702
add jspecify mode flag
msridhar Oct 11, 2022
31a0e4d
check jspecify flag
msridhar Oct 11, 2022
fe66b4a
add test case for nested type parameter instantiation
msridhar Oct 11, 2022
89ca225
nested type
NikitaAware Oct 13, 2022
8ba736b
nested generics type check for new class
NikitaAware Oct 13, 2022
fa627be
Add test - generics check for function return type
NikitaAware Oct 14, 2022
5745cf7
Add - generics check for function return type
NikitaAware Oct 14, 2022
1518629
code cleaning - generics check
NikitaAware Oct 18, 2022
b25ba39
code cleaning - generics check
NikitaAware Oct 18, 2022
bd96079
Merge branch 'master' into add-generics-checks
msridhar Oct 19, 2022
975dccd
Suggested changes
NikitaAware Oct 23, 2022
6d22b00
Suggested changes
NikitaAware Oct 23, 2022
2ddbea9
Suggested changes
NikitaAware Oct 25, 2022
b9cbbff
working changes
NikitaAware Oct 25, 2022
2002aec
working changes
NikitaAware Oct 25, 2022
5c11fbe
suggested changes
NikitaAware Oct 25, 2022
736a613
suggested changes
NikitaAware Oct 27, 2022
80ba7a5
suggested changes
NikitaAware Oct 27, 2022
e1864ee
suggested changes
NikitaAware Oct 27, 2022
8d5e193
extend test
msridhar Oct 27, 2022
91aab18
@Nullable annotation check for Paramterized typed tree
NikitaAware Oct 27, 2022
799f5dc
@Nullable annotation check for Paramterized typed tree
NikitaAware Oct 27, 2022
f042e60
added updates
NikitaAware Nov 1, 2022
852e4b1
added updates
NikitaAware Nov 1, 2022
8b484c2
extra test cases for other annotations
NikitaAware Nov 1, 2022
1727458
extra test cases for other annotations
NikitaAware Nov 1, 2022
7ecc2c4
Merge branch 'master' into add-generics-checks
NikitaAware Nov 1, 2022
f0a0b62
some comments and a todo
msridhar Nov 3, 2022
bc3c0be
reuse code
msridhar Nov 6, 2022
832f733
minor cleanup
msridhar Nov 6, 2022
0b5268c
fix
msridhar Nov 6, 2022
66a1068
Suggested changes
NikitaAware Nov 6, 2022
1bc1ea6
Suggested changes
NikitaAware Nov 6, 2022
cb1690a
Suggested changes
NikitaAware Nov 6, 2022
c523f2d
Javadoc tweaks
msridhar Nov 7, 2022
8cf3819
add private constructor
msridhar Nov 7, 2022
27d5488
suggested changes
NikitaAware Nov 10, 2022
263edac
suggested changes
NikitaAware Nov 10, 2022
2fa8569
suggested changes
NikitaAware Nov 10, 2022
f40a0da
suggested changes
NikitaAware Nov 10, 2022
8308cf6
code cleanup
msridhar Nov 10, 2022
af6404a
tests for error positions
msridhar Nov 10, 2022
ad67e01
Clean up by implementing ParameterizedTypeTreeMatcher
msridhar Nov 11, 2022
67994da
remove extra blank line
msridhar Nov 11, 2022
2631d63
add test
msridhar Nov 11, 2022
36a5c60
suggested changes
NikitaAware Nov 16, 2022
c8ebfe6
suggested changes
NikitaAware Nov 16, 2022
938c595
Merge branch 'master' into add-generics-checks
msridhar Nov 16, 2022
3fb6856
tweak error message
msridhar Nov 16, 2022
ee57c56
clarify test name and purpose
msridhar Nov 16, 2022
7349744
Assignment interface added
NikitaAware Nov 16, 2022
b5eb8a0
structure for assignments checks
NikitaAware Nov 16, 2022
eecc4c3
Assignment changes
NikitaAware Nov 18, 2022
063c580
supertype changes
NikitaAware Dec 7, 2022
696aa90
Merge branch 'master' into assigments1
NikitaAware Dec 9, 2022
823da48
multiple interface implementation
NikitaAware Dec 9, 2022
e26e088
multilevel inheritance
NikitaAware Dec 9, 2022
f7009ae
changes
NikitaAware Dec 9, 2022
3b2cdf1
changes
NikitaAware Dec 9, 2022
d957f56
nested checks
NikitaAware Dec 9, 2022
2d061fc
working changes
NikitaAware Dec 9, 2022
80f296e
working changes
NikitaAware Dec 9, 2022
c33fe3f
Working changes
NikitaAware Dec 9, 2022
31a3dca
updates
NikitaAware Dec 10, 2022
3eca5a3
failing 3 tests
NikitaAware Dec 15, 2022
3435f89
working tests
NikitaAware Dec 16, 2022
7972c05
npe for variable initialization changes
NikitaAware Dec 20, 2022
4924722
npe for variable initialization changes
NikitaAware Dec 20, 2022
35e2bc7
All tests pass including the existing tests
NikitaAware Dec 20, 2022
a59d223
Merge branch 'master' into assigments1
msridhar Dec 21, 2022
25b840b
Merge branch 'master' into assigments1
msridhar Dec 21, 2022
c8456f3
some cleanup
msridhar Dec 21, 2022
945df87
enable check for multiple top-level classes
msridhar Dec 21, 2022
a3fa869
suggested changes - enclosing class member fields
NikitaAware Jan 3, 2023
601f2b5
code cleanup
NikitaAware Jan 3, 2023
a0aacdb
suggested changes
NikitaAware Jan 3, 2023
7b39522
Merge branch 'master' into assigments1
msridhar Jan 4, 2023
84140d0
some suggested changes
NikitaAware Jan 4, 2023
20fae01
suggested changes with working normal typed tree
NikitaAware Jan 4, 2023
c517b4b
Changes with parameterized typed tree without the error generation
NikitaAware Jan 4, 2023
def7ce2
suggested changes with two test cases failing
NikitaAware Jan 4, 2023
75f36df
suggested changes with all passing tests
NikitaAware Jan 4, 2023
0125647
All working changes
NikitaAware Jan 4, 2023
8fc5d18
Continuous integration working
NikitaAware Jan 4, 2023
090ac0c
Continuous integration working
NikitaAware Jan 4, 2023
ba6b229
changes
NikitaAware Jan 4, 2023
bd6700f
minor changes
NikitaAware Jan 4, 2023
fd0b096
fix naming case
msridhar Jan 4, 2023
d5f34f2
failing test
msridhar Jan 4, 2023
01c5503
refactoring and comments
msridhar Jan 4, 2023
25599dd
add a case
msridhar Jan 4, 2023
bf80848
working code with class type
NikitaAware Jan 6, 2023
8ca41d0
minor refactoring
NikitaAware Jan 6, 2023
4a87b6c
minor changes
NikitaAware Jan 6, 2023
44bea9b
code cleaning
NikitaAware Jan 6, 2023
b9a2ed4
code cleaning
NikitaAware Jan 6, 2023
ac7f33a
fancy test works!
msridhar Jan 7, 2023
851fbfa
Merge branch 'master' into assigments1
msridhar Jan 7, 2023
b1119ab
only run check in JSpecify mode
msridhar Jan 7, 2023
92989ec
Fix NullAway errors
msridhar Jan 7, 2023
334d1e8
modified assignment message
NikitaAware Jan 7, 2023
79b474b
remove unneeded suppression
msridhar Jan 7, 2023
05292c0
remove change to build.gradle
msridhar Jan 7, 2023
d9e2689
remove local used only once
msridhar Jan 7, 2023
1cc72f2
cleanup supertypeMatchingLHS
msridhar Jan 7, 2023
85741be
restore private
msridhar Jan 7, 2023
c58d819
add private
msridhar Jan 7, 2023
8829bcd
changed the error message
NikitaAware Jan 8, 2023
fd16446
updated the error message text
NikitaAware Jan 8, 2023
c0fd28e
Type.ClassType suggestion changes
NikitaAware Jan 8, 2023
abe3ed9
changes
NikitaAware Jan 8, 2023
7a18462
changes
NikitaAware Jan 8, 2023
23c8fbb
changes
NikitaAware Jan 8, 2023
88accab
extra test case
NikitaAware Jan 8, 2023
124e7c8
add failing test
msridhar Jan 8, 2023
00802a1
updated logic
NikitaAware Jan 8, 2023
021435a
minor updates
NikitaAware Jan 8, 2023
a12d549
minor code cleaning
NikitaAware Jan 8, 2023
82d9e8d
minor code cleaning
NikitaAware Jan 8, 2023
f381d83
suggested changes
NikitaAware Jan 9, 2023
75234b8
suggested changes
NikitaAware Jan 9, 2023
1be7c40
replaced super type matching lhs with asSuper method
NikitaAware Jan 9, 2023
676e07d
updated assignment checks
NikitaAware Jan 10, 2023
a085443
changes
NikitaAware Jan 10, 2023
c8303d7
changes
NikitaAware Jan 10, 2023
4238a9a
suggested changes
NikitaAware Jan 10, 2023
f5ec4cd
suggested changes
NikitaAware Jan 10, 2023
257c42c
suggested changes
NikitaAware Jan 10, 2023
a9e4890
suggested changes
NikitaAware Jan 10, 2023
f3fd30d
suggested changes
NikitaAware Jan 10, 2023
c2f66e2
Merge branch 'master' into assigments1
msridhar Jan 11, 2023
aeddd14
fix nullaway error
msridhar Jan 11, 2023
c67db12
Merge branch 'master' into assigments1
msridhar Jan 11, 2023
e244e55
fixes
msridhar Jan 11, 2023
53f8546
more cleanup and javadoc
msridhar Jan 11, 2023
0fe788d
Merge branch 'master' into assigments1
msridhar Jan 14, 2023
3fb81c9
Merge branch 'master' into assigments1
msridhar Jan 20, 2023
0bfe208
Merge branch 'master' into assigments1
msridhar Jan 22, 2023
d6bc810
suggested changes in test nestedChecksForAssignmentsMultipleArguments
NikitaAware Jan 23, 2023
3127339
suggested changes in test - superTypeAssignmentChecksSingleInterface
NikitaAware Jan 23, 2023
4aacb5a
suggested indentation changes in test - superTypeAssignmentChecksMult…
NikitaAware Jan 23, 2023
f3e6b45
suggested changes
NikitaAware Jan 23, 2023
38f2ef6
suggested changes
NikitaAware Jan 23, 2023
5245c4d
suggested test for the lambda expressions
NikitaAware Jan 23, 2023
0344360
Java doc for type with preserved annotations
NikitaAware Jan 23, 2023
00cad6f
comments
NikitaAware Jan 23, 2023
d09c190
code cleaning for the tests
NikitaAware Jan 23, 2023
8bb552c
code cleaning for the tests
NikitaAware Jan 23, 2023
0cff82f
changes
NikitaAware Jan 23, 2023
9906f25
suggested changes
NikitaAware Jan 23, 2023
f6dcc69
negative tests
NikitaAware Jan 23, 2023
4323d48
fix formatting in tests
msridhar Jan 23, 2023
5ec8fa1
test cases for diamond operator and the lambdas
NikitaAware Jan 24, 2023
7c07d98
test cases for diamond operator and the lambdas
NikitaAware Jan 24, 2023
6755d66
private fields
NikitaAware Jan 25, 2023
41f45b1
check only for jspecify nullable annotation
NikitaAware Jan 25, 2023
322c3c2
move test method to more appropriate place
msridhar Jan 25, 2023
4a46a46
tweak method reference test
msridhar Jan 25, 2023
4a1ce05
re-add blank line
msridhar Jan 25, 2023
fce345b
clarify method ref test
msridhar Jan 25, 2023
02bbd9f
tweak lambda and diamond operator tests
msridhar Jan 25, 2023
514829d
make test Java 8 compatible
msridhar Jan 26, 2023
2270d8d
Merge branch 'master' into assigments1
msridhar Jan 31, 2023
924883b
Merge branch 'master' into assigments1
msridhar Feb 1, 2023
c070c22
Merge branch 'master' into assigments1
msridhar Feb 6, 2023
e37aa61
Merge branch 'master' into assigments1
msridhar Feb 6, 2023
7412439
suggested changes
NikitaAware Feb 7, 2023
228cf0f
suggested changes
NikitaAware Feb 7, 2023
b7bbf7c
suggested changes
NikitaAware Feb 7, 2023
edb4f86
suggested changes
NikitaAware Feb 7, 2023
18f3134
Merge branch 'master' into assigments1
lazaroclapp Feb 7, 2023
49a113f
function call
NikitaAware Feb 10, 2023
bb9212e
function changes
NikitaAware Feb 10, 2023
bb246e2
tests
NikitaAware Feb 10, 2023
410c130
tests
NikitaAware Feb 10, 2023
de0ca7f
funtions
NikitaAware Feb 10, 2023
105f557
changes
NikitaAware Feb 10, 2023
1490648
fix bad diff with master
msridhar Feb 12, 2023
38429d4
Merge branch 'master' into generics-return-type-changes
msridhar Feb 12, 2023
40ffe4e
Merge branch 'generics-return-type-changes' into generics-ternary-ope…
msridhar Feb 12, 2023
f03bb05
fix nullaway warning
msridhar Feb 12, 2023
51b351f
fix tests
msridhar Feb 12, 2023
309db13
Merge branch 'generics-return-type-changes' into generics-ternary-ope…
msridhar Feb 12, 2023
52825a2
fix
msridhar Feb 12, 2023
b4982ea
change approach
msridhar Feb 12, 2023
6493985
add another test case
msridhar Feb 13, 2023
76093ab
suggested changes
NikitaAware Feb 13, 2023
ea40f7d
suggested changes
NikitaAware Feb 13, 2023
824ed42
error message return changes
NikitaAware Feb 13, 2023
4651fe9
suggested changes
NikitaAware Feb 13, 2023
1921bd1
suggested changes
NikitaAware Feb 14, 2023
090fd56
suggested changes
NikitaAware Feb 14, 2023
6dde586
Merge branch 'generics-return-type-changes' into generics-ternary-ope…
msridhar Feb 14, 2023
e8ff4b3
Update nullaway/src/main/java/com/uber/nullaway/GenericsChecks.java
NikitaAware Feb 15, 2023
142a820
updated error message
NikitaAware Feb 15, 2023
5344b5b
updated error message
NikitaAware Feb 15, 2023
b37c0ab
updated error message
NikitaAware Feb 15, 2023
afcf86e
Merge branch 'generics-return-type-changes' into generics-ternary-ope…
msridhar Feb 15, 2023
4fe9435
updated error message
NikitaAware Feb 15, 2023
d8fae04
update method name
NikitaAware Feb 17, 2023
cbda35b
javadoc
NikitaAware Feb 17, 2023
cd8c8e2
updated error message
NikitaAware Feb 17, 2023
fbc7ed7
updated error message
NikitaAware Feb 17, 2023
f73b54c
suggested changes
NikitaAware Feb 17, 2023
64b9be0
Update nullaway/src/main/java/com/uber/nullaway/GenericsChecks.java
NikitaAware Feb 19, 2023
07dca0a
formatting
msridhar Feb 20, 2023
6287e96
clarify docs and add test
msridhar Feb 20, 2023
4820854
Merge branch 'master' into generics-ternary-operator-assignment-changes
msridhar Feb 22, 2023
dc232c9
minor changes in a test case
NikitaAware Feb 22, 2023
6fae455
Merge branch 'master' into generics-ternary-operator-assignment-changes
msridhar Mar 8, 2023
91e0b36
Merge branch 'master' into generics-ternary-operator-assignment-changes
msridhar Mar 8, 2023
db03146
Merge branch 'master' into generics-ternary-operator-assignment-changes
msridhar Mar 9, 2023
5a3dcf3
Merge branch 'master' into generics-ternary-operator-assignment-changes
msridhar Mar 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions nullaway/src/main/java/com/uber/nullaway/GenericsChecks.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.sun.source.tree.AnnotatedTypeTree;
import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.ConditionalExpressionTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.ParameterizedTypeTree;
Expand Down Expand Up @@ -150,6 +151,23 @@ private static void reportInvalidReturnTypeError(
errorMessage, analysis.buildDescription(tree), state, null));
}

private static void reportMismatchedTypeForTernaryOperator(
Tree tree, Type expressionType, Type subPartType, VisitorState state, NullAway analysis) {
ErrorBuilder errorBuilder = analysis.getErrorBuilder();
ErrorMessage errorMessage =
new ErrorMessage(
ErrorMessage.MessageTypes.ASSIGN_GENERIC_NULLABLE,
String.format(
"Conditional expression must have type "
+ expressionType
+ " but the sub-expression has type "
+ subPartType
+ ", which has mismatched nullability of type parameters"));
state.reportMatch(
errorBuilder.createErrorDescription(
errorMessage, analysis.buildDescription(tree), state, null));
}

/**
* This method returns the type of the given tree, including any type use annotations.
*
Expand Down Expand Up @@ -366,4 +384,49 @@ private Type.ClassType typeWithPreservedAnnotations(ParameterizedTypeTree tree)
type.getEnclosingType(), com.sun.tools.javac.util.List.from(newTypeArgs), type.tsym);
return finalType;
}

/**
* For a conditional expression <em>c</em>, check whether the type parameter nullability for each
* sub-expression of <em>c</em> matches the type parameter nullability of <em>c</em> itself.
*
* <p>Note that the type parameter nullability for <em>c</em> is computed by javac and reflects
* what is required of the surrounding context (an assignment, parameter pass, etc.). It is
* possible that both sub-expressions of <em>c</em> will have identical type parameter
* nullability, but will still not match the type parameter nullability of <em>c</em> itself, due
* to requirements from the surrounding context. In such a case, our error messages may be
* somewhat confusing; we may want to improve this in the future.
*
* @param tree A conditional expression tree to check
*/
public void checkTypeParameterNullnessForConditionalExpression(ConditionalExpressionTree tree) {
if (!config.isJSpecifyMode()) {
return;
}

Tree truePartTree = tree.getTrueExpression();
Tree falsePartTree = tree.getFalseExpression();

Type condExprType = getTreeType(tree);
Type truePartType = getTreeType(truePartTree);
Type falsePartType = getTreeType(falsePartTree);
// The condExpr type should be the least-upper bound of the true and false part types. To check
// the nullability annotations, we check that the true and false parts are assignable to the
// type of the whole expression
if (condExprType instanceof Type.ClassType) {
if (truePartType instanceof Type.ClassType) {
if (!compareNullabilityAnnotations(
(Type.ClassType) condExprType, (Type.ClassType) truePartType)) {
reportMismatchedTypeForTernaryOperator(
truePartTree, condExprType, truePartType, state, analysis);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we avoid the repeated error message of test ternaryMismatchedAssignmentContext simply by adding an early return here? What am I missing?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that we could early return and only report one error there. However, I think what we would really want for that test case is an error message saying the conditional expression as a whole has type A<String>, but the context (i.e., the left-hand side of the assignment) requires type A<@Nullable String> which is mismatched. If we early return, we will report the error for the true part of the conditional expression, but not for the expression as a whole, which I think is still not ideal. If you think just reporting for the true part is better than what we do now, we can add the early return.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to keep this as is for now and working on a better reporting location as a follow up, then, I think...

}
}
if (falsePartType instanceof Type.ClassType) {
if (!compareNullabilityAnnotations(
(Type.ClassType) condExprType, (Type.ClassType) falsePartType)) {
reportMismatchedTypeForTernaryOperator(
falsePartTree, condExprType, falsePartType, state, analysis);
}
}
}
}
}
2 changes: 2 additions & 0 deletions nullaway/src/main/java/com/uber/nullaway/NullAway.java
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,8 @@ public Description matchUnary(UnaryTree tree, VisitorState state) {
public Description matchConditionalExpression(
ConditionalExpressionTree tree, VisitorState state) {
if (withinAnnotatedCode(state)) {
new GenericsChecks(state, config, this)
.checkTypeParameterNullnessForConditionalExpression(tree);
doUnboxingCheck(state, tree.getCondition());
}
return Description.NO_MATCH;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,111 @@ public void genericFunctionReturnTypeMultipleReturnStatementsIfElseBlock() {
.doTest();
}

@Test
public void genericsChecksForTernaryOperator() {
makeHelper()
.addSourceLines(
"Test.java",
"package com.uber;",
"import org.jspecify.annotations.Nullable;",
"class Test {",
"static class A<T extends @Nullable Object> { }",
" static A<String> testPositive(A<String> a, boolean t) {",
" // BUG: Diagnostic contains: Conditional expression must have type",
" A<@Nullable String> t1 = t ? new A<String>() : new A<@Nullable String>();",
" // BUG: Diagnostic contains: Conditional expression must have type",
" return t ? new A<@Nullable String>() : new A<@Nullable String>();",
NikitaAware marked this conversation as resolved.
Show resolved Hide resolved
" }",
" static void testPositiveTernaryMethodArgument(boolean t) {",
" // BUG: Diagnostic contains: Conditional expression must have type",
" A<String> a = testPositive(t ? new A<String>() : new A<@Nullable String>(), t);",
" }",
" static A<@Nullable String> testNegative(boolean t) {",
" A<@Nullable String> t1 = t ? new A<@Nullable String>() : new A<@Nullable String>();",
" return t ? new A<@Nullable String>() : new A<@Nullable String>();",
" }",
"}")
.doTest();
}

@Test
public void ternaryOperatorComplexSubtyping() {
makeHelper()
.addSourceLines(
"Test.java",
"package com.uber;",
"import org.jspecify.annotations.Nullable;",
"class Test {",
" static class A<T extends @Nullable Object> {}",
" static class B<T extends @Nullable Object> extends A<T> {}",
" static class C<T extends @Nullable Object> extends A<T> {}",
" static void testPositive(boolean t) {",
" // BUG: Diagnostic contains: Conditional expression must have type",
" A<@Nullable String> t1 = t ? new B<@Nullable String>() : new C<String>();",
" // BUG: Diagnostic contains: Conditional expression must have type",
" A<@Nullable String> t2 = t ? new C<String>() : new B<@Nullable String>();",
" // BUG: Diagnostic contains:Conditional expression must have type",
" A<@Nullable String> t3 = t ? new B<String>() : new C<@Nullable String>();",
" // BUG: Diagnostic contains: Conditional expression must have type",
" A<String> t4 = t ? new B<@Nullable String>() : new C<@Nullable String>();",
" }",
" static void testNegative(boolean t) {",
" A<@Nullable String> t1 = t ? new B<@Nullable String>() : new C<@Nullable String>();",
" A<@Nullable String> t2 = t ? new C<@Nullable String>() : new B<@Nullable String>();",
" A<String> t3 = t ? new C<String>() : new B<String>();",
" }",
"}")
.doTest();
}

@Test
public void nestedTernary() {
makeHelper()
.addSourceLines(
"Test.java",
"package com.uber;",
"import org.jspecify.annotations.Nullable;",
"class Test {",
" static class A<T extends @Nullable Object> {}",
" static class B<T extends @Nullable Object> extends A<T> {}",
" static class C<T extends @Nullable Object> extends A<T> {}",
" static void testPositive(boolean t) {",
" A<@Nullable String> t1 = t ? new C<@Nullable String>() :",
" // BUG: Diagnostic contains: Conditional expression must have type",
" (t ? new B<@Nullable String>() : new A<String>());",
" }",
" static void testNegative(boolean t) {",
" A<@Nullable String> t1 = t ? new C<@Nullable String>() :",
" (t ? new B<@Nullable String>() : new A<@Nullable String>());",
" }",
"}")
.doTest();
}

@Test
public void ternaryMismatchedAssignmentContext() {
makeHelper()
.addSourceLines(
"Test.java",
"package com.uber;",
"import org.jspecify.annotations.Nullable;",
"class Test {",
"static class A<T extends @Nullable Object> { }",
" static void testPositive(boolean t) {",
" // we get two errors here, one for each sub-expression; perhaps ideally we would report",
" // just one error (that the ternary operator has type A<String> but the assignment LHS",
" // has type A<@Nullable String>), but implementing that check in general is",
" // a bit tricky",
" A<@Nullable String> t1 = t",
" // BUG: Diagnostic contains: Conditional expression must have type",
" ? new A<String>()",
" // BUG: Diagnostic contains: Conditional expression must have type",
" : new A<String>();",
" }",
"}")
.doTest();
}

private CompilationTestHelper makeHelper() {
return makeTestHelperWithArgs(
Arrays.asList(
Expand Down