-
Notifications
You must be signed in to change notification settings - Fork 337
Initial inference for wildcards #1549
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
Changes from all commits
6468f79
a69452f
93658b0
acf7a46
145780e
4dc86d5
0762977
ab188c1
d9f11aa
b3cbb66
644df50
00e94a0
1b1216b
1ea5c3b
2f2c832
e6e36a1
56d03b3
271d1d4
9378e23
0a0e73a
25f57aa
f57f949
6e84a58
5acb656
36ffec3
adb858c
272c447
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -293,13 +293,15 @@ public Type visitMethodType(Type.MethodType t, Type other) { | |
|
|
||
| @Override | ||
| public Type visitClassType(Type.ClassType t, Type other) { | ||
| if (other instanceof Type.WildcardType wt && wt.kind == BoundKind.EXTENDS) { | ||
| // As a temporary measure, we restore nullability annotations from the upper bound of the | ||
| // wildcard. | ||
| // TODO revisit this decision when we add fuller support for inference and wildcards. | ||
| return visit(t, wt.getExtendsBound()); | ||
| if (other instanceof Type.WildcardType wt) { | ||
| // When the other type is a wildcard, restore nullability annotations from the bound that | ||
| // determines the functional interface type. | ||
| if (wt.kind == BoundKind.EXTENDS) { | ||
| return visit(t, wt.getExtendsBound()); | ||
| } else if (wt.kind == BoundKind.SUPER) { | ||
| return visit(t, wt.getSuperBound()); | ||
| } | ||
| } | ||
|
Comment on lines
+296
to
304
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check if there are test cases covering UNBOUND wildcards flowing through this visitor
rg -n --type=java 'visitClassType.*Wildcard|UNBOUND' nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java
rg -n --type=java '\<\?\>' nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.java | head -20Repository: uber/NullAway Length of output: 130 🏁 Script executed: #!/bin/bash
# Read the TypeSubstitutionUtils.java file to see the full context around lines 296-304
wc -l nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 138 🏁 Script executed: #!/bin/bash
# Read the relevant section of TypeSubstitutionUtils.java
sed -n '290,315p' nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 1129 🏁 Script executed: #!/bin/bash
# Find GenericsUtils.java and check the wildcardUpperBound method
fd -n GenericsUtils.java nullaway/src/main/javaRepository: uber/NullAway Length of output: 288 🏁 Script executed: #!/bin/bash
# Search for UNBOUND keyword in the codebase
rg -n "BoundKind.UNBOUND" nullaway/src/main/java/Repository: uber/NullAway Length of output: 187 🏁 Script executed: #!/bin/bash
# Search for test cases related to wildcards
fd -n "WildcardTests.java" nullaway/src/test/javaRepository: uber/NullAway Length of output: 288 🏁 Script executed: #!/bin/bash
# Find GenericsUtils.java
find nullaway/src/main/java -name "GenericsUtils.java"Repository: uber/NullAway Length of output: 126 🏁 Script executed: #!/bin/bash
# Find WildcardTests.java
find nullaway/src/test/java -name "WildcardTests.java"Repository: uber/NullAway Length of output: 126 🏁 Script executed: #!/bin/bash
# Search for wildcardUpperBound method
rg -n "wildcardUpperBound" nullaway/src/main/java/Repository: uber/NullAway Length of output: 1483 🏁 Script executed: #!/bin/bash
# Search for how UNBOUND wildcards are handled in generics code
rg -n "BoundKind\|UNBOUND" nullaway/src/main/java/com/uber/nullaway/generics/ -A 2 -B 2Repository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Read the GenericsUtils.java file to understand wildcardUpperBound
cat -n nullaway/src/main/java/com/uber/nullaway/generics/GenericsUtils.java | head -80Repository: uber/NullAway Length of output: 3711 🏁 Script executed: #!/bin/bash
# Search for UNBOUND handling patterns
rg -n "UNBOUND" nullaway/src/main/java/com/uber/nullaway/generics/Repository: uber/NullAway Length of output: 425 🏁 Script executed: #!/bin/bash
# Check WildcardTests.java for test coverage of UNBOUND wildcards
cat -n nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.java | head -100Repository: uber/NullAway Length of output: 4631 🏁 Script executed: #!/bin/bash
# Search for similar wildcard handling patterns in other visitors
rg -n "instanceof.*WildcardType" nullaway/src/main/java/com/uber/nullaway/generics/ -A 5 -B 1Repository: uber/NullAway Length of output: 5547 🏁 Script executed: #!/bin/bash
# Check if visitClassType is called with UNBOUND wildcards in practice
rg -n "visitClassType" nullaway/src/main/java/com/uber/nullaway/generics/ -B 2 -A 2Repository: uber/NullAway Length of output: 3135 🏁 Script executed: #!/bin/bash
# Read more of TypeSubstitutionUtils.java to understand the context and purpose
sed -n '260,320p' nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 2698 🏁 Script executed: #!/bin/bash
# Search for test cases with unbounded wildcards (just "?")
rg -n '\?\>' nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.javaRepository: uber/NullAway Length of output: 130 🏁 Script executed: #!/bin/bash
# Check if there are any tests with super wildcards
rg -n '\? super' nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.javaRepository: uber/NullAway Length of output: 2881 🏁 Script executed: #!/bin/bash
# Search for any existing UNBOUND handling or comments about it
rg -n "UNBOUND" nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Check if bound field can be null for WildcardType
rg -n "wildcardType.bound|wt.bound" nullaway/src/main/java/com/uber/nullaway/generics/ -B 2 -A 2Repository: uber/NullAway Length of output: 674 🏁 Script executed: #!/bin/bash
# Look at the visitWildcardType method in TypeSubstitutionUtils to see how it handles wildcards
sed -n '321,345p' nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 830 🏁 Script executed: #!/bin/bash
# Check if there are any comments or documentation about why UNBOUND is not handled
sed -n '290,310p' nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java | cat -nRepository: uber/NullAway Length of output: 1046 🏁 Script executed: #!/bin/bash
# Verify if wt.bound can be null and check the null handling in GenericsUtils pattern
rg -n "bound == null|bound != null" nullaway/src/main/java/com/uber/nullaway/generics/GenericsUtils.javaRepository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Check if there are any other visitors that handle UNBOUND explicitly
rg -n "BoundKind.UNBOUND" nullaway/src/main/java/com/uber/nullaway/generics/ -B 2 -A 2Repository: uber/NullAway Length of output: 668 🏁 Script executed: #!/bin/bash
# Check if there are tests for unbounded wildcards by looking for patterns like Foo<?>
rg -n 'Foo<.*>' nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.java | grep -v extends | grep -v super | head -20Repository: uber/NullAway Length of output: 1458 🏁 Script executed: #!/bin/bash
# Check if the code actually processes UNBOUND wildcards and what happens
rg -n "RestoreNullnessAnnotationsVisitor\|visitClassType" nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java -B 5 -A 15 | head -60Repository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Verify what updateDirectNullabilityAnnotationsForType does with WildcardType
rg -n "updateDirectNullabilityAnnotationsForType" nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java -A 5 | head -40Repository: uber/NullAway Length of output: 1206 🏁 Script executed: #!/bin/bash
# Read the updateDirectNullabilityAnnotationsForType method fully
sed -n '362,390p' nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 1261 🏁 Script executed: #!/bin/bash
# Check the git history or comments around this code
git log --oneline -20 -- nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 89 🏁 Script executed: #!/bin/bash
# Look for any test that specifically checks UNBOUND wildcard behavior
rg -n "unboundedFoo\|Foo<\?>" nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.java -B 3 -A 8Repository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Check what the actual test expectations are for unbounded wildcards
sed -n '270,320p' nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.javaRepository: uber/NullAway Length of output: 2626 🏁 Script executed: #!/bin/bash
# Look at the context around line 275 test with unbounded foo
rg -n "unboundedFoo" nullaway/src/test/java/com/uber/nullaway/jspecify/WildcardTests.java -B 5 -A 15Repository: uber/NullAway Length of output: 1671 🏁 Script executed: #!/bin/bash
# Check if bound field is populated for UNBOUND wildcards
rg -n "\.bound\s*=" nullaway/src/main/java/com/uber/nullaway/generics/ -B 2 -A 2Repository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Check the commit context for the RestoreNullnessAnnotationsVisitor code
git show 272c447 --statRepository: uber/NullAway Length of output: 27203 🏁 Script executed: #!/bin/bash
# Search for usages of RestoreNullnessAnnotationsVisitor to understand when it's invoked
rg -n "RestoreNullnessAnnotationsVisitor\|new RestoreNullnessAnnotationsVisitor" nullaway/src/main/java/ -B 2 -A 2Repository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Check if there's a way for UNBOUND to be processed through the formal type parameter bound
rg -n "wt.bound\|wildcardType.bound" nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 39 🏁 Script executed: #!/bin/bash
# Look at the broader context of how RestoreNullnessAnnotationsVisitor is used
rg -n "new RestoreNullnessAnnotationsVisitor\|RestoreNullnessAnnotationsVisitor(" nullaway/src/main/java/com/uber/nullaway/generics/ -B 3 -A 3Repository: uber/NullAway Length of output: 254 🏁 Script executed: #!/bin/bash
# Look at the broader context of how RestoreNullnessAnnotationsVisitor is used
rg -n "RestoreNullnessAnnotationsVisitor" nullaway/src/main/java/com/uber/nullaway/generics/ -B 3 -A 3Repository: uber/NullAway Length of output: 2508 🏁 Script executed: #!/bin/bash
# Check what happens in the UNBOUND case - does it fall through intentionally or by omission?
# Look for any comments or documentation about wildcard handling
sed -n '290,340p' nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.javaRepository: uber/NullAway Length of output: 1782 Handle UNBOUND wildcards by extracting the formal type parameter's upper bound. The code explicitly extracts bounds for For UNBOUND wildcards, consider handling the case explicitly: Suggested approach if (other instanceof Type.WildcardType wt) {
// When the other type is a wildcard, restore nullability annotations from the bound that
// determines the functional interface type.
if (wt.kind == BoundKind.EXTENDS) {
return visit(t, wt.getExtendsBound());
} else if (wt.kind == BoundKind.SUPER) {
return visit(t, wt.getSuperBound());
+ } else if (wt.kind == BoundKind.UNBOUND && wt.bound != null) {
+ return visit(t, wt.bound.getUpperBound());
+ }
}🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There cannot be explicit nullability annotations for the unbound case
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
✏️ Learnings added
🧠 Learnings used |
||
|
|
||
| Type updated = updateDirectNullabilityAnnotationsForType(t, other); | ||
| if (!(other instanceof Type.ClassType)) { | ||
| return updated; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.