xref: /aosp_15_r20/external/jspecify/samples/README.md (revision 2167191df2fa07300797f1ac5b707370b5f38c48)
1*2167191dSAndroid Build Coastguard Worker# Sample inputs
2*2167191dSAndroid Build Coastguard Worker
3*2167191dSAndroid Build Coastguard WorkerCurrently, the main purpose of these samples is to act as a source of test cases
4*2167191dSAndroid Build Coastguard Workerfor authors of nullness checkers that wish to use JSpecify nullness information.
5*2167191dSAndroid Build Coastguard Worker
6*2167191dSAndroid Build Coastguard Worker## Disclaimers
7*2167191dSAndroid Build Coastguard Worker
8*2167191dSAndroid Build Coastguard WorkerThese sample inputs are informative, not normative.
9*2167191dSAndroid Build Coastguard Worker
10*2167191dSAndroid Build Coastguard WorkerThey use annotations whose names and meanings are not finalized. Notably, they
11*2167191dSAndroid Build Coastguard Workercurrently use an explicit `@NullnessUnspecified` annotation, even though that
12*2167191dSAndroid Build Coastguard Workerannotation was not part of our 0.1 milestone and will quite possibly not be part
13*2167191dSAndroid Build Coastguard Workerof our 1.0 release. (Still, we haven't yet removed the `@NullnessUnspecified`
14*2167191dSAndroid Build Coastguard Workerusages: First, we're not yet certain whether we'll include that annotation or
15*2167191dSAndroid Build Coastguard Workernot. Second, the annotation provides an easier way to demonstrate rules that can
16*2167191dSAndroid Build Coastguard Workerarise without it but are easier to demonstrate with it. We probably wouldn't
17*2167191dSAndroid Build Coastguard Workerwrite such samples if we were starting from scratch today, but we wrote them
18*2167191dSAndroid Build Coastguard Workerwhen we started, and they appear to provide some value on net.)
19*2167191dSAndroid Build Coastguard Worker
20*2167191dSAndroid Build Coastguard WorkerThey have mostly not been code reviewed.
21*2167191dSAndroid Build Coastguard Worker
22*2167191dSAndroid Build Coastguard WorkerWe do not know if this is even the format that we want our sample inputs to be
23*2167191dSAndroid Build Coastguard Workerin.
24*2167191dSAndroid Build Coastguard Worker
25*2167191dSAndroid Build Coastguard WorkerWhatever our final samples look like, we do **not** expect to present them as
26*2167191dSAndroid Build Coastguard Worker"conformance tests" that require any behavior from tools:
27*2167191dSAndroid Build Coastguard Worker
28*2167191dSAndroid Build Coastguard Worker-   JSpecify nullness information may be of use to many kinds of tools, not just
29*2167191dSAndroid Build Coastguard Worker    "nullness checkers." But these samples are written in a way that makes them
30*2167191dSAndroid Build Coastguard Worker    most useful to authors of nullness checkers. Authors of other tools -- those
31*2167191dSAndroid Build Coastguard Worker    that render API descriptions, generate source code, perform refactorings,
32*2167191dSAndroid Build Coastguard Worker    etc. -- are not best served by the samples' focus on
33*2167191dSAndroid Build Coastguard Worker    `jspecify_nullness_mismatch`, etc.
34*2167191dSAndroid Build Coastguard Worker
35*2167191dSAndroid Build Coastguard Worker-   The goal of JSpecify is to provide one source of nullness information. Tools
36*2167191dSAndroid Build Coastguard Worker    may use some, all, or none of that information. They may also use
37*2167191dSAndroid Build Coastguard Worker    information from other sources.
38*2167191dSAndroid Build Coastguard Worker
39*2167191dSAndroid Build Coastguard Worker    -   Some examples of "information from other sources":
40*2167191dSAndroid Build Coastguard Worker
41*2167191dSAndroid Build Coastguard Worker        -   looking at the *implementation* of a method to decide whether it can
42*2167191dSAndroid Build Coastguard Worker            return `null`
43*2167191dSAndroid Build Coastguard Worker        -   looking at non-JSpecify nullness annotations in code
44*2167191dSAndroid Build Coastguard Worker        -   looking at "overlay" or "stub" information about nullness for
45*2167191dSAndroid Build Coastguard Worker            well-known APIs
46*2167191dSAndroid Build Coastguard Worker        -   looking at whether the parameter to a call to `Map.get` is known to
47*2167191dSAndroid Build Coastguard Worker            be present in that map
48*2167191dSAndroid Build Coastguard Worker        -   defining a rule to treat all unannotated type usages the same, when
49*2167191dSAndroid Build Coastguard Worker            the JSpecify rules give some of them "unspecified nullness"
50*2167191dSAndroid Build Coastguard Worker
51*2167191dSAndroid Build Coastguard Worker-   Based on the information they have available for any given piece of code,
52*2167191dSAndroid Build Coastguard Worker    tools always have the option to issue a warning / error / other diagnostic
53*2167191dSAndroid Build Coastguard Worker    for that code, and they always have the option not to. (Even for a tool that
54*2167191dSAndroid Build Coastguard Worker    uses *all* JSpecify information and *only* JSpecify information, that
55*2167191dSAndroid Build Coastguard Worker    information is, at its heart, *information* for tools to apply as their
56*2167191dSAndroid Build Coastguard Worker    authors see fit.)
57*2167191dSAndroid Build Coastguard Worker
58*2167191dSAndroid Build Coastguard Worker## Syntax
59*2167191dSAndroid Build Coastguard Worker
60*2167191dSAndroid Build Coastguard Worker<!-- TODO: Update links to point to the markup-format spec and glossary. -->
61*2167191dSAndroid Build Coastguard Worker
62*2167191dSAndroid Build Coastguard WorkerA special comment on a given line of a `.java` file provides information about
63*2167191dSAndroid Build Coastguard Workerthe following line.
64*2167191dSAndroid Build Coastguard Worker
65*2167191dSAndroid Build Coastguard WorkerThe first three special comments indicate that JSpecify annotations are applied
66*2167191dSAndroid Build Coastguard Workerin ways that are
67*2167191dSAndroid Build Coastguard Worker[unrecognized](http://jspecify.org/spec#recognized-locations-type-use). Tools
68*2167191dSAndroid Build Coastguard Workerare likely to report an error in the case of the first two, somewhat less likely
69*2167191dSAndroid Build Coastguard Workerto report an error in the case of the third (since they might choose to give
70*2167191dSAndroid Build Coastguard Workertheir meaning to annotations there), and not *obligated* to do anything for any
71*2167191dSAndroid Build Coastguard Workerof the cases:
72*2167191dSAndroid Build Coastguard Worker
73*2167191dSAndroid Build Coastguard Worker-   `jspecify_conflicting_annotations`: for cases like `@Nullable
74*2167191dSAndroid Build Coastguard Worker    @NullnessUnspecified Foo`
75*2167191dSAndroid Build Coastguard Worker
76*2167191dSAndroid Build Coastguard Worker-   `jspecify_nullness_intrinsically_not_nullable`: for cases like `@Nullable
77*2167191dSAndroid Build Coastguard Worker    int`
78*2167191dSAndroid Build Coastguard Worker
79*2167191dSAndroid Build Coastguard Worker-   `jspecify_unrecognized_location`: for the other cases in which JSpecify does
80*2167191dSAndroid Build Coastguard Worker    not give meaning to an annotation, like `class @Nullable Foo {}`.
81*2167191dSAndroid Build Coastguard Worker
82*2167191dSAndroid Build Coastguard WorkerThe last two comments indicate a nullness violation: an inconsistency between
83*2167191dSAndroid Build Coastguard Workertwo annotations, or between annotations and source code. You can think of these
84*2167191dSAndroid Build Coastguard Workeras extending the normal JLS type rules to cover types that have been augmented
85*2167191dSAndroid Build Coastguard Workerwith nullness information. (For example, the value of a `return` statement must
86*2167191dSAndroid Build Coastguard Workerbe convertible to the method's return type, and the receiver in a method call
87*2167191dSAndroid Build Coastguard Workershould not be `@Nullable`.) Nullness checkers are likely to report an error for
88*2167191dSAndroid Build Coastguard Workereach `jspecify_nullness_mismatch` comment, are likely to make many different
89*2167191dSAndroid Build Coastguard Workerdecisions in whether to issues a diagnostic (error, warning, or no diagnostic)
90*2167191dSAndroid Build Coastguard Workerfor any particular `jspecify_nullness_not_enough_information` comment, and are
91*2167191dSAndroid Build Coastguard Workernot *obligated* to do anything for any particular comment. (For some background
92*2167191dSAndroid Build Coastguard Workeron that, see the disclaimers above. Also, note that a nullness checker can be
93*2167191dSAndroid Build Coastguard Workersound even if it does not issue errors for some cases of
94*2167191dSAndroid Build Coastguard Worker`jspecify_nullness_mismatch` or `jspecify_nullness_not_enough_information`!)
95*2167191dSAndroid Build Coastguard Worker
96*2167191dSAndroid Build Coastguard Worker-   `jspecify_nullness_mismatch`
97*2167191dSAndroid Build Coastguard Worker
98*2167191dSAndroid Build Coastguard Worker-   `jspecify_nullness_not_enough_information`: for nullness violations that
99*2167191dSAndroid Build Coastguard Worker    involve
100*2167191dSAndroid Build Coastguard Worker    [unspecified nullness](https://docs.google.com/document/d/1KQrBxwaVIPIac_6SCf--w-vZBeHkTvtaqPSU_icIccc/edit#bookmark=id.xb9w6p3ilsq3).
101*2167191dSAndroid Build Coastguard Worker
102*2167191dSAndroid Build Coastguard WorkerTODO: Consider additional features:
103*2167191dSAndroid Build Coastguard Worker
104*2167191dSAndroid Build Coastguard Worker-   multiline comments
105*2167191dSAndroid Build Coastguard Worker-   other locations for comments
106*2167191dSAndroid Build Coastguard Worker-   multiple findings per line/comment
107*2167191dSAndroid Build Coastguard Worker-   comments that apply to larger ranges -- possibly to syntax elements (like
108*2167191dSAndroid Build Coastguard Worker    statements) rather than lines
109*2167191dSAndroid Build Coastguard Worker-   comments that apply only to a particular part of the line
110*2167191dSAndroid Build Coastguard Worker
111*2167191dSAndroid Build Coastguard Worker## Directory structure
112*2167191dSAndroid Build Coastguard Worker
113*2167191dSAndroid Build Coastguard WorkerSee
114*2167191dSAndroid Build Coastguard Worker[JSpecify: test-data format: Directory structure](https://docs.google.com/document/d/1JVH2p61kReO8bW4AKnbkpybPYlUulVmyNrR1WRIEE_k/edit#bookmark=id.2t1r58i5a03s).
115*2167191dSAndroid Build Coastguard WorkerTODO(#134): Inline that here if Tagir can sign the CLA and contribute it.
116*2167191dSAndroid Build Coastguard Worker
117*2167191dSAndroid Build Coastguard WorkerAdditionally:
118*2167191dSAndroid Build Coastguard Worker
119*2167191dSAndroid Build Coastguard WorkerFully qualified class names must be unique across all directories.
120*2167191dSAndroid Build Coastguard Worker
121*2167191dSAndroid Build Coastguard Worker> This permits all files to be compiled in a single tool invocation.
122*2167191dSAndroid Build Coastguard Worker
123*2167191dSAndroid Build Coastguard WorkerTODO: Consider requiring that all individual-file samples be in the top-level
124*2167191dSAndroid Build Coastguard Workerdirectory.
125*2167191dSAndroid Build Coastguard Worker
126*2167191dSAndroid Build Coastguard WorkerEach file must contain a single top-level class. TODO(#133): Consider relaxing
127*2167191dSAndroid Build Coastguard Workerthis.
128*2167191dSAndroid Build Coastguard Worker
129*2167191dSAndroid Build Coastguard WorkerTODO: Consider requiring a file's path to match its package and class:
130*2167191dSAndroid Build Coastguard Worker
131*2167191dSAndroid Build Coastguard Worker-   individual-file samples: `Foo.java` for `Foo`
132*2167191dSAndroid Build Coastguard Worker
133*2167191dSAndroid Build Coastguard Worker-   full-directory samples: `sampleFoo/Foo.java` for `Foo`,
134*2167191dSAndroid Build Coastguard Worker    `sampleFoo/bar/Foo.java` for `bar.Foo`
135*2167191dSAndroid Build Coastguard Worker
136*2167191dSAndroid Build Coastguard Worker-   We may need additional accommodations for JPMS support to demonstrate
137*2167191dSAndroid Build Coastguard Worker    module-level defaulting.
138*2167191dSAndroid Build Coastguard Worker
139*2167191dSAndroid Build Coastguard Worker## Restrictions
140*2167191dSAndroid Build Coastguard Worker
141*2167191dSAndroid Build Coastguard WorkerFiles must be UTF-8 encoded.
142*2167191dSAndroid Build Coastguard Worker
143*2167191dSAndroid Build Coastguard WorkerFiles must contain only printable ASCII characters and `\n`.
144*2167191dSAndroid Build Coastguard Worker
145*2167191dSAndroid Build Coastguard WorkerFiles must be compatible with Java 8. TODO(#131): Decide how to label files that
146*2167191dSAndroid Build Coastguard Workerrequire a higher version so that we can allow them. (But still encourage
147*2167191dSAndroid Build Coastguard Workersticking to Java 8 except for tests that specifically exercise newer features.)
148*2167191dSAndroid Build Coastguard Worker
149*2167191dSAndroid Build Coastguard WorkerFiles must compile without error using stock javac.
150*2167191dSAndroid Build Coastguard Worker
151*2167191dSAndroid Build Coastguard WorkerFiles must not depend on any classes other than the JSpecify annotations. This
152*2167191dSAndroid Build Coastguard Workerincludes the Java platform APIs. Exception: Files may use `java.lang.Object`,
153*2167191dSAndroid Build Coastguard Workerbut they still must not use its methods.
154*2167191dSAndroid Build Coastguard Worker
155*2167191dSAndroid Build Coastguard Worker> For example, files may use `Object` as a bound, parameter, or return type.
156*2167191dSAndroid Build Coastguard Worker
157*2167191dSAndroid Build Coastguard WorkerFiles should avoid depending on the presence of absence of "smart" checker
158*2167191dSAndroid Build Coastguard Workerfeatures, such as:
159*2167191dSAndroid Build Coastguard Worker
160*2167191dSAndroid Build Coastguard Worker-   looking inside the body of a method to determine what parameters it
161*2167191dSAndroid Build Coastguard Worker    dereferences or what it returns
162*2167191dSAndroid Build Coastguard Worker
163*2167191dSAndroid Build Coastguard Worker    -   To that end, prefer abstract methods when practical.
164*2167191dSAndroid Build Coastguard Worker
165*2167191dSAndroid Build Coastguard Worker-   flow-sensitive typing
166*2167191dSAndroid Build Coastguard Worker
167*2167191dSAndroid Build Coastguard WorkerWe also encourage writing files that demonstrate individual behaviors in
168*2167191dSAndroid Build Coastguard Workerisolation. For example, we encourage writing files to minimize how much they
169*2167191dSAndroid Build Coastguard Workerrely on type inference -- except, of course, for any files explicitly intended
170*2167191dSAndroid Build Coastguard Workerto demonstrate type inference.
171*2167191dSAndroid Build Coastguard Worker
172*2167191dSAndroid Build Coastguard Worker## More TODOs
173*2167191dSAndroid Build Coastguard Worker
174*2167191dSAndroid Build Coastguard WorkerTODO: Consider how to map between samples and related GitHub issues (comments,
175*2167191dSAndroid Build Coastguard Workerfilenames?).
176