Skip to content
Open
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
411 commits
Select commit Hold shift + click to select a range
f9e3c8a
remove warning suppression, it is fixed otherwise
Jun 20, 2025
5bf6243
wrap call to store.getValue in try-catch
Jun 20, 2025
2d903bf
consider iterables as collections as well
Jun 20, 2025
457577d
fix interning error
Jun 20, 2025
0be8bf8
add missing documentation
Jun 20, 2025
0355af2
remove deprecated comment
Jun 20, 2025
384fba1
check @NotOwningCollection returns
Jun 20, 2025
34283fd
add tests for return to @NotOwningCollection
Jun 20, 2025
02b6d94
add unrefinement test for collection ownership type system
Jun 20, 2025
98c831b
replace unnecessary .equals with ==
Jun 20, 2025
3025ad3
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 20, 2025
395653b
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 21, 2025
a11f29a
add utility method: is MethodInvocationTree call to hasNext()?
Jun 21, 2025
17e413d
make getCalledMethods in CmAtf public
Jun 21, 2025
987f30c
add utility method to rlccmatf to get store after block
Jun 21, 2025
0ab52aa
add loop body analysis
Jun 21, 2025
9a74bf6
handle IteratedCollectionElement JavaExpression
Jun 21, 2025
4111e30
remove obligation in else edge of fulfilling loop conditional block
Jun 21, 2025
4337abf
fix doc
Jun 21, 2025
8a25348
adapt test outcomes after implementing fulfillment
Jun 21, 2025
f5bac6c
formatting
Jun 22, 2025
161b0d9
make interning checker happy
Jun 22, 2025
171c64a
add throws declaration
Jun 22, 2025
66361fd
remove println as it makes wpi fail
Jun 22, 2025
dc0e806
CollectionOwnership transfer func for fulfilling loop
Jun 22, 2025
026c94b
override .equals(Object) for CollectionObligation
Jun 22, 2025
c732cee
tests for loop body analysis
Jun 22, 2025
81dd857
mark desugared assignment
Jun 22, 2025
fea139b
special case desugared array assignment
Jun 22, 2025
e5e29da
make interning checker happy one more time
Jun 22, 2025
8e49c89
more loop body analysis tests
Jun 22, 2025
7419cfa
expand doc on assignment node marking of desugaring
Jun 22, 2025
8fbd9ff
fix method call to desugaring marking in cfg translation
Jun 22, 2025
3819423
formatting
Jun 22, 2025
794a2bf
fix call to isdesugared()
Jun 22, 2025
95dc4f8
add infrastructure for loop-body-analysis on normal for-loops
Jun 22, 2025
1c3ad70
add treeutils helper methods
Jun 22, 2025
ecf6bc6
adapt consistency analyzer for loop body analysis over normal for-loo…
Jun 22, 2025
c1232cb
pattern match fulfilling for-loops on AST
Jun 22, 2025
3f75eca
add normal for loop tests
Jun 22, 2025
23b66c0
fix wpi-many caused crash on for-loop patternmatch
Jun 23, 2025
8ae0796
add missing @param
Jun 23, 2025
779b39c
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 23, 2025
9fe30ef
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jun 23, 2025
326b418
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 23, 2025
f7c8de9
use annotatedtypemirror to decide resource collection after defaulting
Jun 24, 2025
61c79ae
add test cases for new assignment behavior
Jun 24, 2025
0e007b1
fix crash in pattern match of loops
Jun 24, 2025
0da4598
consider iterators collections, but special case for obligation creation
Jun 24, 2025
7e503e9
formatting
Jun 24, 2025
af5fe4b
add PolyOwningCollection
Jun 24, 2025
95f2170
annotate iterator override in issue6030
Jun 24, 2025
5d79525
add collection ownership receiver annotation
Jun 24, 2025
331931e
default resource collection constructor returns no OCwO
Jun 24, 2025
123f26d
fix return rule for resource collections
Jun 24, 2025
d9d7feb
fix tests to account for enhanced precision of new defaults
Jun 24, 2025
ee95caa
add CollectionOwnershipStore and Analysis
Jun 25, 2025
ee0ce6d
add collectionfielddestructor postcon anno
Jun 25, 2025
12ae8fc
doc
Jun 25, 2025
b2505b7
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 25, 2025
ce34a10
add support for @OC fields
Jun 25, 2025
73af398
demand @CreatesCollectionObligation method invocs on fields to have @…
Jun 25, 2025
75f3cbf
add test for @OC fields
Jun 25, 2025
6134f55
make missing.creates.mustcall.for slightly more generic
Jun 25, 2025
fdf9b0a
add method deciding whether rc field is owning or not
Jun 26, 2025
0ae2cf5
introduce owning rc field as @OCwO in constructor
Jun 26, 2025
dcde6c3
prevent ownership transfer out of owning rc field
Jun 26, 2025
febc5cb
fix how owning rc fields are decided in COVisitor
Jun 26, 2025
e19a61c
check owning rc field assignments in consistency analyzer
Jun 26, 2025
2468321
more field tests
Jun 26, 2025
73b3985
Javadoc
mernst Jun 26, 2025
2b6456c
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
mernst Jun 26, 2025
21f3503
move logic for parsing JavaExp from string from visitor to atf
Jun 26, 2025
efa1d38
fix how @OC and owning rc field are decided
Jun 26, 2025
bf14a97
check field accesses to prevent accessing foreign owning rc fields
Jun 26, 2025
7fd44cc
new field tests
Jun 26, 2025
f3442c3
comment field null test, not implemented yet
Jun 26, 2025
eb46285
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jun 26, 2025
3dfe32b
Merge branch 'master' of https://github.com/typetools/checker-framewo…
Jun 26, 2025
5474b79
add missing doc
Jun 26, 2025
4700443
please new preferences of formatter
Jun 27, 2025
410f092
use new isOwningCollectionField in costore as well
Jun 27, 2025
77d6946
isocfield now expects element instead of tree
Jun 27, 2025
01ae15c
add missing @param
Jun 27, 2025
d7e3c0c
fix crash due to receiver not in store
Jun 27, 2025
a201ecb
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 27, 2025
620b82e
manual update
Jun 27, 2025
3181578
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jun 27, 2025
08a7c08
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 27, 2025
076f0b7
fix rlc-collections manual
Jun 28, 2025
b386e9e
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jun 28, 2025
b9bf410
fix quotes
Jun 28, 2025
fcf9e05
suppress this-escape warning for calling postInit()
Jun 28, 2025
fab3eb9
fix nullness crash
Jun 28, 2025
dd92896
make @OCBottom and @OCwO illegal manual annotations
Jun 28, 2025
6a46cfb
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 5, 2025
56e8fd4
disallow owning rc field assignments with @OC rhs
Jul 5, 2025
627cc6e
keep @NotOwningCollection rc fields in store as well
Jul 5, 2025
0a7d4f2
fix how return statements are checked for @OC return vals
Jul 5, 2025
ffd8f25
allow assignments to final field
Jul 5, 2025
d935a35
disallow static rc fields
Jul 6, 2025
23a2fcd
remove obligation of rhs in assignment to owning rc final field lhs
Jul 6, 2025
c8d95a0
improve error message for foreign rc field access
Jul 6, 2025
8ddb042
add field test cases
Jul 6, 2025
a62bede
remove array support
Jul 6, 2025
5f32f89
fix test outcomse after making List#get not owning
Jul 6, 2025
ab5b2a2
remove array tests
Jul 6, 2025
9e3c23a
fix collections rlc manual section with manu feedback
Jul 7, 2025
bbb7ef8
also require createsmcfor(this) for field asgnment with noc rhs
Jul 7, 2025
3ade7ed
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 9, 2025
62c4299
maps are now also resource collections
Jul 9, 2025
66901ee
remove expected warning for type.arg because map can now hold non-emp…
Jul 9, 2025
be87c39
@OwningCollection and @NotOwningCollection are inheritable!!!!
Jul 9, 2025
79506bd
polyowning inherited
Jul 9, 2025
71ae840
only collections with one typearg are rc
Jul 9, 2025
b1687a6
fix crash when annotated type not available
Jul 14, 2025
2b13a8d
Format
mernst Jul 21, 2025
518e749
fix loopbodyanalysis (fix by Suzanne)
Jul 21, 2025
fe206ee
no errors for map.get
Jul 21, 2025
4c3dc9c
uncomment now working loop body analysis tests
Jul 21, 2025
14d37bf
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jul 21, 2025
82717fc
formatting
Jul 21, 2025
f474bc5
suppress interning warning
Jul 22, 2025
398d16c
fix crash in for-loop pattern match
Jul 22, 2025
f30abbb
make collectionownership annotations inheritable
Jul 22, 2025
80cd91a
formating
Jul 22, 2025
b10609c
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 22, 2025
9a4d4ef
suzanne's fix for the afu build file
Jul 22, 2025
33d7b64
annotate afu for collection ownership checker
Jul 23, 2025
3347442
warning suppressions in afu for collection ownership checker
Jul 23, 2025
555194e
add poly annotation as field
Jul 23, 2025
0f25e74
don't inherit polyoc annotation
Jul 23, 2025
a4f1a3f
propagate annotations from parameter decl to use site
Jul 23, 2025
64b1855
adapt annos&suppressions for afu subproject after not inheriting poly…
Jul 23, 2025
03efa5f
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 23, 2025
4433b46
Add Javadoc
mernst Jul 23, 2025
ffa65ba
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
mernst Jul 23, 2025
b39a77a
Add Javadoc
mernst Jul 23, 2025
fe92dab
Use %n, not \n, in format strings
mernst Jul 24, 2025
10a30c2
Documentation improvements
mernst Jul 24, 2025
eaadec9
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 24, 2025
ceebfff
Documentation improvements
mernst Jul 25, 2025
6e95c34
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 25, 2025
9549bfc
Use "true if" instead of "whether"
mernst Jul 25, 2025
116f596
Improve Javadoc style
mernst Jul 25, 2025
6b0b327
Rename variable
mernst Jul 25, 2025
346b9ed
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 25, 2025
a012a9d
Use curly braces around then and else clauses
mernst Jul 25, 2025
96bd8a1
Documentation tweaks and improve efficiency by doing cheap test first
mernst Jul 25, 2025
a961341
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 27, 2025
5d55958
Improve Javadoc style
mernst Jul 27, 2025
9a0246b
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 27, 2025
7db0254
Checkpoint
mernst Jul 27, 2025
83fed79
Variable names
mernst Jul 30, 2025
b343553
Documentation for `defaultCreateAbstractValue`
mernst Jul 30, 2025
20aa7d7
Checkpoint
mernst Jul 30, 2025
13c41f0
Merge ../checker-framework-fork-mernst-branch-defaultCreateAbstractVa…
mernst Jul 30, 2025
94c2730
Add curly braces around `then` clauses
mernst Jul 30, 2025
76358b6
Merge ../checker-framework-fork-mernst-branch-curly-braces into rlc-c…
mernst Jul 30, 2025
0e80e9d
Add curly braces
mernst Jul 30, 2025
41396e0
Code review edits
mernst Jul 30, 2025
a00e883
Code review edits
mernst Jul 30, 2025
2e81982
Revert experimental change
mernst Jul 30, 2025
37c76a5
Make `insertIntoStores` non-static
mernst Jul 30, 2025
66d4ca8
Documentation fixes
mernst Jul 30, 2025
a6e60b7
Remove suppression
mernst Jul 30, 2025
6f47713
Add `@NotOwning` annotation
mernst Jul 31, 2025
8c1d87a
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 3, 2025
f9da2da
Suppress warnings
mernst Aug 5, 2025
f4d47c6
Temporary warning suppression
mernst Aug 5, 2025
eaa5492
more annotations for rlc4c
Aug 6, 2025
e3e06d9
add receiver annotation
Aug 6, 2025
596f2e1
add comment
Aug 6, 2025
6b17e65
add rlc4c annos
Aug 6, 2025
dada8a3
fix javadoc
Aug 6, 2025
7bcf851
remove unnecessary warning suppression
Aug 7, 2025
343f76a
Add annotations
mernst Aug 7, 2025
8477297
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
mernst Aug 7, 2025
7f51f70
Add Javadoc
mernst Aug 7, 2025
19f39a8
Add annotations, suppress warnings
mernst Aug 7, 2025
8e2fc86
import `@Nullable`
mernst Aug 7, 2025
1480bed
Move annotations
mernst Aug 7, 2025
9d12532
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 8, 2025
251cb94
address code review
Aug 8, 2025
02cc724
address code review: remove createSourceVisitor override in coc
Aug 8, 2025
72bdbc8
remove unnecessary nullness checks
Aug 8, 2025
d552b3e
make mcatf a field in coatf
Aug 8, 2025
aab1708
remove catch bugincf to make error explicit
Aug 8, 2025
bba3c2f
remove mcoeobligationaltering loop wrapper class
Aug 8, 2025
d915819
replace catch (Exception) with catch (BugInCF)
Aug 8, 2025
b88929c
minor changes code review
Aug 8, 2025
0ab02c8
minor changes code review
Aug 8, 2025
03aed4a
fix expected test outcome after renaming an error code
Aug 8, 2025
3bf63c4
minor fixes code review
Aug 8, 2025
8ed76d7
formatting
Aug 8, 2025
d00a615
minor changes code review
Aug 8, 2025
3aeafe7
fix faulty link
Aug 8, 2025
02fa7e8
use old collectors method to prevent runtime error
Aug 9, 2025
c53a155
prevent crash in loop body analysis
Aug 9, 2025
845006a
catch BugInCF if tree has unexpected shape when deciding rc
Aug 9, 2025
1b89b55
prevent crash when rhs of oc field assignment not in store
Aug 10, 2025
e325d51
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 12, 2025
adfc3ab
Fix a typo
kelloggm Aug 13, 2025
f9a0665
clarifications and typo fixes in the manual
kelloggm Aug 13, 2025
73d6163
explanatory comment
kelloggm Aug 13, 2025
7322107
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 17, 2025
4504294
clarify comment
Aug 17, 2025
912aa9a
remove commented out code
Aug 17, 2025
639ff0d
add explanation why loop matching is in mc-visitor
Aug 17, 2025
26a43c1
update explanation for expected test behavior
Aug 17, 2025
4b2a223
add a test case
Aug 17, 2025
4bf1f92
remove commented out defaults for OCBottom
Aug 17, 2025
65abe44
move field example code before explanation in manual
Aug 17, 2025
3d1a831
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Aug 17, 2025
5179206
comment out mentions of iterator support in rl manual
Aug 17, 2025
062b104
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 20, 2025
ccc78f1
Merge branch 'master' into rlc-collections-redesign
mernst Aug 20, 2025
ec858ae
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 24, 2025
157054a
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 26, 2025
b4fe2ef
parser moved
Aug 26, 2025
fcfc684
add obligation upon CreatsCollectionObligation even for @OC
Aug 26, 2025
7f155e1
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 28, 2025
0913ff3
Merge branch 'master' into rlc-collections-redesign
mernst Sep 1, 2025
a8d2991
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Sep 2, 2025
a5030a7
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Sep 8, 2025
0de2d9c
Fix bug in CFG construction for preincrement
mernst Sep 9, 2025
9d61bff
Fixup
mernst Sep 9, 2025
11ee250
Return locally
mernst Sep 9, 2025
6645c05
Merge ../checker-framework-fork-mernst-branch-partially-undo-9bc061c-…
mernst Sep 9, 2025
1d12e3d
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Sep 9, 2025
49a566f
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Sep 10, 2025
50ff472
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Oct 3, 2025
23da55c
fix spelling mistake in manual
Oct 7, 2025
8b35b86
add explanation when catching InvalidLoopBodyAnalysis Exception
Oct 7, 2025
e40bbbf
mark method as @override
Oct 7, 2025
a552a56
prefer this.equals over other.equals
Oct 7, 2025
04284ad
remove array example from rlc4c manual
Oct 7, 2025
af26a63
fix typo in comment
Oct 7, 2025
54b6000
add override decorators to test file
Oct 7, 2025
69175cf
explicitly use MustCall({}) instead of MustCall
Oct 7, 2025
f945491
remove exceptional stores noop
Oct 7, 2025
527004c
annotated @CreatesCollectionObligation as documented
Oct 7, 2025
3b3a8df
fix doc for createscollectionobligation
Oct 7, 2025
b105a8a
improve javadoc
Oct 8, 2025
a8111ef
address trivial coderabbit PR comments
Oct 8, 2025
c2309f0
revert error message to previous
Oct 8, 2025
2d53603
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Oct 9, 2025
50394ff
Comment improvements
mernst Oct 9, 2025
4afb91f
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Oct 22, 2025
7018049
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Oct 23, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
import org.checkerframework.afu.scenelib.type.BoundedType;
import org.checkerframework.afu.scenelib.type.DeclaredType;
import org.checkerframework.afu.scenelib.type.Type;
import org.checkerframework.checker.collectionownership.qual.PolyOwningCollection;
import org.checkerframework.checker.interning.qual.Interned;
import org.checkerframework.checker.mustcall.qual.NotOwning;
import org.objectweb.asm.TypePath;

/**
Expand Down Expand Up @@ -185,7 +187,7 @@ public int size() {
}

@Override
public Iterator<Insertion> iterator() {
public @PolyOwningCollection Iterator<Insertion> iterator(@PolyOwningCollection Insertions this) {
return new Iterator<Insertion>() {
private Iterator<Map<String, Set<Insertion>>> miter = store.values().iterator();
// These two fields are initially empty iterators, but are set the first time that hasNext is
Expand All @@ -210,7 +212,7 @@ public boolean hasNext() {
}

@Override
public Insertion next() {
public @NotOwning Insertion next() {
if (hasNext()) {
return iiter.next();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
import java.util.NoSuchElementException;
import java.util.Objects;
import org.checkerframework.afu.annotator.find.CaseUtils;
import org.checkerframework.checker.collectionownership.qual.NotOwningCollection;
import org.checkerframework.checker.collectionownership.qual.PolyOwningCollection;
import org.plumelib.util.ArraysPlume;

/** A path through the AST. */
Expand Down Expand Up @@ -295,7 +297,7 @@ public static Comparator<ASTPath> getComparator() {

// TODO: replace w/ skip list?
@Override
public Iterator<ASTEntry> iterator() {
public @PolyOwningCollection Iterator<ASTEntry> iterator(@PolyOwningCollection ASTPath this) {
ImmutableStack<ASTEntry> s = this;
int n = size();
ASTEntry[] a = new ASTEntry[n];
Expand Down Expand Up @@ -1460,18 +1462,33 @@ private static <T, S extends ImmutableStack<T>> S extend(T el, S s0) {
}
}

public boolean isEmpty() {
/**
* Returns true if the stack is empty.
*
* @return true if the stack is empty
*/
public boolean isEmpty(@NotOwningCollection ImmutableStack<E> this) {
return size == 0;
}

public E peek() {
/**
* Returns the top element of the stack, without modifying the stack.
*
* @return the top element of the stack
*/
public E peek(@NotOwningCollection ImmutableStack<E> this) {
if (isEmpty()) {
throw new IllegalStateException("peek() on empty stack");
}
return elem;
}

public ImmutableStack<E> pop() {
/**
* Returns all of the stack except the top element.
*
* @return all of the stack except the top element
*/
public ImmutableStack<E> pop(@NotOwningCollection ImmutableStack<E> this) {
if (isEmpty()) {
throw new IllegalStateException("pop() on empty stack");
}
Expand All @@ -1482,11 +1499,21 @@ public ImmutableStack<E> push(E elem) {
return extend(elem, this);
}

public int size() {
/**
* Returns the size: the number of elements in the stack.
*
* @return the size of this stack
*/
public int size(@NotOwningCollection ImmutableStack<E> this) {
return size;
}

/** Return the index-th element of this stack. */
/**
* Returns the index-th element of this stack.
*
* @param index which element to return
* @return the index-th element of this stack
*/
public E get(int index) {
Comment on lines 1511 to 1517
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider annotating push and get for completeness.

To keep the API surface consistent, annotate push/get receivers as @NotOwningCollection too.

-  public ImmutableStack<E> push(E elem) {
+  public ImmutableStack<E> push(@NotOwningCollection ImmutableStack<E> this, E elem) {
     return extend(elem, this);
   }
@@
-  public E get(int index) {
+  public E get(@NotOwningCollection ImmutableStack<E> this, int index) {
     int n = size();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Returns the index-th element of this stack.
*
* @param index which element to return
* @return the index-th element of this stack
*/
public E get(int index) {
public ImmutableStack<E> push(@NotOwningCollection ImmutableStack<E> this, E elem) {
return extend(elem, this);
}
/**
* Returns the index-th element of this stack.
*
* @param index which element to return
* @return the index-th element of this stack
*/
public E get(@NotOwningCollection ImmutableStack<E> this, int index) {
int n = size();
// …rest of method unchanged…
🤖 Prompt for AI Agents
In
annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java
around lines 1511-1517, the get method (and the push method elsewhere in this
class) should have their receivers annotated as @NotOwningCollection to keep the
API consistent; update both method signatures to add the receiver annotation
(e.g., change "public E get(int index)" to include the receiver annotation on
the implicit this, and likewise add @NotOwningCollection to the push method's
receiver) so the methods are explicitly marked as not owning the collection.

int n = size();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.checkerframework.afu.scenelib.field.ArrayAFT;
import org.checkerframework.afu.scenelib.field.ClassTokenAFT;
import org.checkerframework.afu.scenelib.field.EnumAFT;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.signature.qual.ClassGetName;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
Expand Down Expand Up @@ -430,7 +431,8 @@ public FieldAnnotationSceneWriter(int api, String name, FieldVisitor fv) {
}

@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
@SuppressWarnings("nullness:override.return") // ASM lacks (some?) @Nullable annotations
public @Nullable AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
existingFieldAnnotations.add(descriptor);

// If annotation exists in scene, and in overwrite mode,
Expand All @@ -443,7 +445,8 @@ public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
}

@Override
public AnnotationVisitor visitTypeAnnotation(
@SuppressWarnings("nullness:override.return") // ASM lacks (some?) @Nullable annotations
public @Nullable AnnotationVisitor visitTypeAnnotation(
int typeRef, TypePath typePath, String descriptor, boolean visible) {
// typeRef: FIELD
existingFieldAnnotations.add(descriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,27 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.checkerframework.checker.collectionownership.qual.OwningCollection;
import org.checkerframework.checker.collectionownership.qual.PolyOwningCollection;
import org.checkerframework.checker.mustcall.qual.NotOwning;
import org.checkerframework.checker.mustcall.qual.Owning;

/**
* A simple implementation of {@link KeyedSet} backed by an insertion-order {@link
* java.util.LinkedHashMap} and its {@link java.util.LinkedHashMap#values() value collection}.
*
* @param <K> the type of keys
* @param <V> the type of values
*/
public class LinkedHashKeyedSet<K, V> extends AbstractSet<V> implements KeyedSet<K, V> {
/** Produces a key for a value. */
private final Keyer<? extends K, ? super V> keyer;

private final Map<K, V> theMap = new LinkedHashMap<>();
/** The map that backs this set. */
// Declared as LinkedHashMap because some implementations of Map prohibit null keys.
private final LinkedHashMap<K, V> theMap = new LinkedHashMap<>();

Comment on lines 23 to 26
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Prefer interface type for the field to reduce coupling

Declaring theMap as Map preserves flexibility; the runtime implementation remains LinkedHashMap. The null-keys rationale doesn’t require the declared type to be LinkedHashMap.

-import java.util.LinkedHashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
@@
-  /** The map that backs this set. */
-  // Declared as LinkedHashMap because some implementations of Map prohibit null keys.
-  private final LinkedHashMap<K, V> theMap = new LinkedHashMap<>();
+  /** The map that backs this set (insertion-ordered). */
+  private final Map<K, V> theMap = new LinkedHashMap<>();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/** The map that backs this set. */
// Declared as LinkedHashMap because some implementations of Map prohibit null keys.
private final LinkedHashMap<K, V> theMap = new LinkedHashMap<>();
// --- imports ---
import java.util.LinkedHashMap;
import java.util.Map;
// --- inside the class ---
/** The map that backs this set (insertion-ordered). */
private final Map<K, V> theMap = new LinkedHashMap<>();
🤖 Prompt for AI Agents
In
annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java
around lines 23 to 26, the field is declared as a concrete LinkedHashMap which
increases coupling; change the field declaration to use the Map interface (e.g.,
private final Map<K, V> theMap = new LinkedHashMap<>();) while keeping the
runtime implementation as LinkedHashMap, retain or update the comment about
null-key behavior, and verify no code elsewhere relies on LinkedHashMap-specific
APIs—if it does, adjust those usages or narrow the type only where necessary.

/** The values in the set. Implemented as a view into the map. */
final Collection<V> theValues = theMap.values();

/**
Expand Down Expand Up @@ -44,7 +54,7 @@ public boolean hasNext() {
}

@Override
public V next() {
public @NotOwning V next() {
return itr.next();
}

Expand All @@ -57,7 +67,7 @@ public void remove() {
}

@Override
public Iterator<V> iterator() {
public Iterator<V> iterator(@PolyOwningCollection LinkedHashKeyedSet<K, V> this) {
return new KeyedSetIterator();
}

Expand All @@ -71,7 +81,15 @@ public <T> T[] toArray(T[] a) {
return theValues.toArray(a);
}

private boolean checkAdd(int behavior, V old) {
/**
* Prepares for adding an element to this. Removes the given element if {@code behavior} is
* REPLACE.
*
* @param behavior what action this method should take
* @param old the element to be removed, if {@code behavior} is REPLACE
* @return true if an element was removed
*/
private boolean checkAdd(@OwningCollection LinkedHashKeyedSet<K, V> this, int behavior, V old) {
switch (behavior) {
case REPLACE:
remove(old);
Expand All @@ -90,7 +108,11 @@ private static boolean eq(Object x, Object y) {
}

@Override
public V add(V o, int conflictBehavior, int equalBehavior) {
public V add(
@OwningCollection LinkedHashKeyedSet<K, V> this,
V o,
int conflictBehavior,
int equalBehavior) {
K key = keyer.getKeyFor(o);
V old = theMap.get(key);
if (old == null
Expand All @@ -100,12 +122,12 @@ public V add(V o, int conflictBehavior, int equalBehavior) {
}

@Override
public boolean add(V o) {
public boolean add(@Owning V o) {
return add(o, THROW_EXCEPTION, IGNORE) == null;
}

@Override
public boolean remove(Object o) {
public boolean remove(@OwningCollection LinkedHashKeyedSet<K, V> this, Object o) {
return theValues.remove(o);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.checkerframework.checker.mustcall.qual.NotOwning;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* A {@link WrapperMap} is a map all of whose methods delegate by default to those of a supplied
Expand Down Expand Up @@ -39,7 +41,7 @@ public Set<java.util.Map.Entry<K, V>> entrySet() {
}

@Override
public V get(Object key) {
public @NotOwning @Nullable V get(Object key) {
return back.get(key);
}

Expand All @@ -54,7 +56,8 @@ public Set<K> keySet() {
}

@Override
public V put(K key, V value) {
@SuppressWarnings("keyfor:contracts.postcondition") // uses a delegate map
public @NotOwning @Nullable V put(K key, V value) {
return back.put(key, value);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.checkerframework.checker.collectionownership.qual;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.checkerframework.framework.qual.InheritedAnnotation;
import org.checkerframework.framework.qual.PostconditionAnnotation;

/**
* The annotated method destructs the given resource collection fields. That is, this method calls
* all required methods on their elements.
*
* <pre><code>
* {@literal @}CollectionFieldDestructor("socketList")
* void close() {
* for (Socket s : this.socketList) {
* try {
* s.close();
* } catch (Exception e) {}
* }
* }
* </code></pre>
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@PostconditionAnnotation(qualifier = OwningCollectionWithoutObligation.class)
@InheritedAnnotation
public @interface CollectionFieldDestructor {
/**
* Returns the resource collection fields whose collection obligation the destructor fulfills.
*
* @return the resource collection fields whose collection obligation the destructor fulfills
*/
String[] value();
Comment on lines +33 to +39
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Mark expressions as @JavaExpression for better tooling

Annotate value() so IDE tooling and the framework parse field references reliably.

Apply:

+import org.checkerframework.framework.qual.JavaExpression;
@@
-  String[] value();
+  @JavaExpression String[] value();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public @interface CollectionFieldDestructor {
/**
* Returns the resource collection fields whose collection obligation the destructor fulfills.
*
* @return the resource collection fields whose collection obligation the destructor fulfills
*/
String[] value();
import org.checkerframework.framework.qual.JavaExpression;
public @interface CollectionFieldDestructor {
/**
* Returns the resource collection fields whose collection obligation the destructor fulfills.
*
* @return the resource collection fields whose collection obligation the destructor fulfills
*/
@JavaExpression String[] value();
}
🤖 Prompt for AI Agents
In
checker-qual/src/main/java/org/checkerframework/checker/collectionownership/qual/CollectionFieldDestructor.java
around lines 33–39, the value() element is a String[] of field references but
lacks the @JavaExpression annotation, which improves IDE and framework parsing;
add an import for org.checkerframework.framework.qual.JavaExpression and
annotate the value() method with @JavaExpression (e.g., public @JavaExpression
String[] value()) so tooling recognizes the strings as Java expressions.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.checkerframework.checker.collectionownership.qual;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.checkerframework.framework.qual.InheritedAnnotation;

/**
* A method carrying this annotation creates a {@code CollectionObligation} for the receiver
* collection.
*
* <p>Consider a call to a {@code CreatesCollectionObligation}-annotated method. If the receiver is
* of type {@code @OwningCollectionWithoutObligation}, it is unrefined to {@code @OwningCollection},
* and a CollectionObligation is created for each {@code @MustCall} method of the type variable of
* the receiver.
*
* <p>This annotation should only be used on method declarations of collections, as defined by the
* CollectionOwnershipChecker, that is, {@code java.lang.Iterable} and {@code java.util.Iterator}
* implementations.
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@InheritedAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface CreatesCollectionObligation {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.checkerframework.checker.collectionownership.qual;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.checkerframework.framework.qual.SubtypeOf;

/**
* An expression of type {@code NotOwningCollection} is a non-owning reference to a resource
* collection/array. Because it does not own the underlying collection/array, it cannot add or
* remove elements from it.
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf({})
public @interface NotOwningCollection {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.checkerframework.checker.collectionownership.qual;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.checkerframework.framework.qual.SubtypeOf;

/**
* An expression of type {@code @OwningCollection} is a resource collection/array that definitely
* owns the underlying collection/array. It can add or remove elements from the collection/array.
*
* <p>The annotated expression (or one of its aliases) must either call the methods in the
* {@code @MustCall} type of its elements on all of its elements, or pass on the obligation to
* another expression.
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf({NotOwningCollection.class})
public @interface OwningCollection {}
Loading
Loading