tree: 53298df428eb73cb1e5f901f6a3dcdac89e639ad [path history] [tgz]
  1. annotatedBoundsOfWildcard/
  2. defaults/
  3. fullyQualified/
  4. ignoreAnnotations/
  5. implementWithNullableTypeArgument/
  6. memberSelectNonExpression/
  7. nonPlatformTypeParameter/
  8. nullnessUnspecifiedTypeParameter/
  9. packageDefault/
  10. selfType/
  11. simple/
  12. typeArgumentsFromParameterBounds/
  13. typeParameterBounds/
  14. wildcardsWithDefault/
  15. AnnotatedInnerOfNonParameterized.java
  16. AnnotatedInnerOfParameterized.java
  17. AnnotatedReceiver.java
  18. AnnotatedTypeParameter.java
  19. AnnotatedTypeParameterUnspec.java
  20. AnnotatedWildcard.java
  21. AnnotatedWildcardUnspec.java
  22. ArraySameType.java
  23. ArraySubtype.java
  24. AssignmentAsExpression.java
  25. AugmentedInferenceAgreesWithBaseInference.java
  26. BoundedTypeVariableReturn.java
  27. CaptureAsInferredTypeArgument.java
  28. CaptureConversionForSubtyping.java
  29. CaptureConvertedToObject.java
  30. CaptureConvertedToObjectUnionNull.java
  31. CaptureConvertedToObjectUnspec.java
  32. CaptureConvertedToOther.java
  33. CaptureConvertedToOtherUnionNull.java
  34. CaptureConvertedToOtherUnspec.java
  35. CaptureConvertedUnionNullToObject.java
  36. CaptureConvertedUnionNullToObjectUnionNull.java
  37. CaptureConvertedUnionNullToObjectUnspec.java
  38. CaptureConvertedUnionNullToOther.java
  39. CaptureConvertedUnionNullToOtherUnionNull.java
  40. CaptureConvertedUnionNullToOtherUnspec.java
  41. CaptureConvertedUnspecToObject.java
  42. CaptureConvertedUnspecToObjectUnionNull.java
  43. CaptureConvertedUnspecToObjectUnspec.java
  44. CaptureConvertedUnspecToOther.java
  45. CaptureConvertedUnspecToOtherUnionNull.java
  46. CaptureConvertedUnspecToOtherUnspec.java
  47. CastOfCaptureOfNotNullMarkedUnboundedWildcardForObjectBoundedTypeParameter.java
  48. CastOfCaptureOfUnboundedWildcardForNotNullMarkedObjectBoundedTypeParameter.java
  49. CastOfCaptureOfUnboundedWildcardForObjectBoundedTypeParameter.java
  50. CastToPrimitive.java
  51. CastWildcardToTypeVariable.java
  52. Catch.java
  53. ClassLiteral.java
  54. ClassToObject.java
  55. ClassToSelf.java
  56. ComplexParametric.java
  57. ConcatResult.java
  58. ConflictingAnnotations.java
  59. Constants.java
  60. ContainmentExtends.java
  61. ContainmentExtendsBounded.java
  62. ContainmentSuper.java
  63. ContainmentSuperVsExtends.java
  64. ContainmentSuperVsExtendsSameType.java
  65. ContravariantReturns.java
  66. CovariantReturns.java
  67. DereferenceClass.java
  68. DereferenceIntersection.java
  69. DereferenceTernary.java
  70. DereferenceTypeVariable.java
  71. EnumAnnotations.java
  72. ExtendsSameType.java
  73. ExtendsTypeVariableImplementedForNullableTypeArgument.java
  74. ExtendsVsExtendsNullable.java
  75. IfCondition.java
  76. InferenceChoosesNullableTypeVariable.java
  77. InstanceOfCheck.java
  78. IntersectionSupertype.java
  79. LocalVariable.java
  80. MultiBoundTypeVariableToObject.java
  81. MultiBoundTypeVariableToObjectUnionNull.java
  82. MultiBoundTypeVariableToObjectUnspec.java
  83. MultiBoundTypeVariableToOther.java
  84. MultiBoundTypeVariableToOtherUnionNull.java
  85. MultiBoundTypeVariableToOtherUnspec.java
  86. MultiBoundTypeVariableToSelf.java
  87. MultiBoundTypeVariableToSelfUnionNull.java
  88. MultiBoundTypeVariableToSelfUnspec.java
  89. MultiBoundTypeVariableUnionNullToObject.java
  90. MultiBoundTypeVariableUnionNullToObjectUnionNull.java
  91. MultiBoundTypeVariableUnionNullToObjectUnspec.java
  92. MultiBoundTypeVariableUnionNullToOther.java
  93. MultiBoundTypeVariableUnionNullToOtherUnionNull.java
  94. MultiBoundTypeVariableUnionNullToOtherUnspec.java
  95. MultiBoundTypeVariableUnionNullToSelf.java
  96. MultiBoundTypeVariableUnionNullToSelfUnionNull.java
  97. MultiBoundTypeVariableUnionNullToSelfUnspec.java
  98. MultiBoundTypeVariableUnspecToObject.java
  99. MultiBoundTypeVariableUnspecToObjectUnionNull.java
  100. MultiBoundTypeVariableUnspecToObjectUnspec.java
  101. MultiBoundTypeVariableUnspecToOther.java
  102. MultiBoundTypeVariableUnspecToOtherUnionNull.java
  103. MultiBoundTypeVariableUnspecToOtherUnspec.java
  104. MultiBoundTypeVariableUnspecToSelf.java
  105. MultiBoundTypeVariableUnspecToSelfUnionNull.java
  106. MultiBoundTypeVariableUnspecToSelfUnspec.java
  107. MultiplePathsToTypeVariable.java
  108. NonConstantPrimitives.java
  109. NonNullProjection.java
  110. NonNullSimple.java
  111. NoPathToTypeVariableMinusNull.java
  112. NotNullMarkedAnnotatedInnerOfNonParameterized.java
  113. NotNullMarkedAnnotatedInnerOfParameterized.java
  114. NotNullMarkedAnnotatedTypeParameter.java
  115. NotNullMarkedAnnotatedTypeParameterUnspec.java
  116. NotNullMarkedAnnotatedWildcard.java
  117. NotNullMarkedAnnotatedWildcardUnspec.java
  118. NotNullMarkedClassToSelf.java
  119. NotNullMarkedConcatResult.java
  120. NotNullMarkedContainmentExtends.java
  121. NotNullMarkedContainmentSuper.java
  122. NotNullMarkedContainmentSuperVsExtends.java
  123. NotNullMarkedIfCondition.java
  124. NotNullMarkedInferenceChoosesNullableTypeVariable.java
  125. NotNullMarkedLocalVariable.java
  126. NotNullMarkedOverrides.java
  127. NotNullMarkedTypeVariableBound.java
  128. NotNullMarkedUnboxing.java
  129. NotNullMarkedUseOfTypeVariable.java
  130. NotNullMarkedUseOfTypeVariableAsTypeArgument.java
  131. NotNullMarkedUseOfWildcardAsTypeArgument.java
  132. NullCheck.java
  133. NullCheckTypeVariable.java
  134. NullCheckTypeVariableUnionNullBound.java
  135. NullCheckTypeVariableUnspecBound.java
  136. NullLiteralToClass.java
  137. NullLiteralToTypeVariable.java
  138. NullLiteralToTypeVariableUnionNull.java
  139. NullLiteralToTypeVariableUnspec.java
  140. NullMarkedDirectUseOfNotNullMarkedBoundedTypeVariable.java
  141. NullnessDoesNotAffectOverloadSelection.java
  142. NullUnmarkedUndoesNullMarked.java
  143. NullUnmarkedUndoesNullMarkedForWildcards.java
  144. ObjectAsSuperOfTypeVariable.java
  145. OutOfBoundsTypeVariable.java
  146. OverrideParameters.java
  147. OverrideParametersThatAreTypeVariables.java
  148. OverrideReturns.java
  149. ParameterizedWithTypeVariableArgumentToSelf.java
  150. PrimitiveAnnotations.java
  151. PrimitiveAnnotationsUnspec.java
  152. README.md
  153. SameTypeObject.java
  154. SameTypeTypeVariable.java
  155. SuperNullableForNonNullableTypeParameter.java
  156. SuperObject.java
  157. SuperObjectUnionNull.java
  158. SuperObjectUnspec.java
  159. SuperSameType.java
  160. SuperTypeVariable.java
  161. SuperTypeVariableUnionNull.java
  162. SuperTypeVariableUnspec.java
  163. SuperVsObject.java
  164. SuperVsSuperNullable.java
  165. Ternary.java
  166. TypeArgumentOfTypeVariableBound.java
  167. TypeArgumentOfWildcardBound.java
  168. TypeVariableMinusNullVsTypeVariable.java
  169. TypeVariableToObject.java
  170. TypeVariableToObjectUnionNull.java
  171. TypeVariableToObjectUnspec.java
  172. TypeVariableToParent.java
  173. TypeVariableToParentUnionNull.java
  174. TypeVariableToParentUnspec.java
  175. TypeVariableToSelf.java
  176. TypeVariableToSelfUnionNull.java
  177. TypeVariableToSelfUnspec.java
  178. TypeVariableUnionNullToObject.java
  179. TypeVariableUnionNullToObjectUnionNull.java
  180. TypeVariableUnionNullToObjectUnspec.java
  181. TypeVariableUnionNullToParent.java
  182. TypeVariableUnionNullToParentUnionNull.java
  183. TypeVariableUnionNullToParentUnspec.java
  184. TypeVariableUnionNullToSelf.java
  185. TypeVariableUnionNullToSelfUnionNull.java
  186. TypeVariableUnionNullToSelfUnspec.java
  187. TypeVariableUnspecToObject.java
  188. TypeVariableUnspecToObjectUnionNull.java
  189. TypeVariableUnspecToObjectUnspec.java
  190. TypeVariableUnspecToParent.java
  191. TypeVariableUnspecToParentUnionNull.java
  192. TypeVariableUnspecToParentUnspec.java
  193. TypeVariableUnspecToSelf.java
  194. TypeVariableUnspecToSelfUnionNull.java
  195. TypeVariableUnspecToSelfUnspec.java
  196. Unboxing.java
  197. UninitializedField.java
  198. UnionTypeArgumentWithUseSite.java
  199. UnrecognizedLocationsMisc.java
  200. UnspecifiedClassTypeArgumentForNonNullableParameter.java
  201. UnspecifiedTypeArgumentForNonNullableParameter.java
  202. UnspecifiedTypeArgumentForNonNullableParameterRepeatedSubstitution.java
  203. UnspecifiedTypeArgumentForNonNullableParameterUseUnspec.java
  204. UnspecifiedTypeVariableTypeArgumentForNonNullableParameter.java
  205. UseOfTypeVariableAsTypeArgument.java
  206. UseOfTypeVariableUnionNullAsTypeArgument.java
  207. UseOfTypeVariableUnspecAsTypeArgument.java
  208. WildcardBoundWithAnnotations.java
  209. WildcardCapturesToBoundOfTypeParameterNotToTypeVariableItself.java
samples/README.md

Sample inputs

Currently, the main purpose of these samples is to act as a source of test cases for authors of nullness checkers that wish to use JSpecify nullness information.

Disclaimers

These sample inputs are informative, not normative.

They use annotations whose names and meanings are not finalized. Notably, they currently use an explicit @NullnessUnspecified annotation, even though that annotation was not part of our 0.1 milestone and will quite possibly not be part of our 1.0 release. (Still, we haven‘t yet removed the @NullnessUnspecified usages: First, we’re not yet certain whether we‘ll include that annotation or not. Second, the annotation provides an easier way to demonstrate rules that can arise without it but are easier to demonstrate with it. We probably wouldn’t write such samples if we were starting from scratch today, but we wrote them when we started, and they appear to provide some value on net.)

They have mostly not been code reviewed.

We do not know if this is even the format that we want our sample inputs to be in.

Whatever our final samples look like, we do not expect to present them as “conformance tests” that require any behavior from tools:

  • JSpecify nullness information may be of use to many kinds of tools, not just “nullness checkers.” But these samples are written in a way that makes them most useful to authors of nullness checkers. Authors of other tools -- those that render API descriptions, generate source code, perform refactorings, etc. -- are not best served by the samples' focus on jspecify_nullness_mismatch, etc.

  • The goal of JSpecify is to provide one source of nullness information. Tools may use some, all, or none of that information. They may also use information from other sources.

    • Some examples of “information from other sources”:

      • looking at the implementation of a method to decide whether it can return null
      • looking at non-JSpecify nullness annotations in code
      • looking at “overlay” or “stub” information about nullness for well-known APIs
      • looking at whether the parameter to a call to Map.get is known to be present in that map
      • defining a rule to treat all unannotated type usages the same, when the JSpecify rules give some of them “unspecified nullness”
  • Based on the information they have available for any given piece of code, tools always have the option to issue a warning / error / other diagnostic for that code, and they always have the option not to. (Even for a tool that uses all JSpecify information and only JSpecify information, that information is, at its heart, information for tools to apply as their authors see fit.)

Syntax

A special comment on a given line of a .java file provides information about the following line.

The first three special comments indicate that JSpecify annotations are applied in ways that are unrecognized. Tools are likely to report an error in the case of the first two, somewhat less likely to report an error in the case of the third (since they might choose to give their meaning to annotations there), and not obligated to do anything for any of the cases:

  • jspecify_conflicting_annotations: for cases like @Nullable @NullnessUnspecified Foo

  • jspecify_nullness_intrinsically_not_nullable: for cases like @Nullable int

  • jspecify_unrecognized_location: for the other cases in which JSpecify does not give meaning to an annotation, like class @Nullable Foo {}.

The last two comments indicate a nullness violation: an inconsistency between two annotations, or between annotations and source code. You can think of these as extending the normal JLS type rules to cover types that have been augmented with nullness information. (For example, the value of a return statement must be convertible to the method's return type, and the receiver in a method call should not be @Nullable.) Nullness checkers are likely to report an error for each jspecify_nullness_mismatch comment, are likely to make many different decisions in whether to issues a diagnostic (error, warning, or no diagnostic) for any particular jspecify_nullness_not_enough_information comment, and are not obligated to do anything for any particular comment. (For some background on that, see the disclaimers above. Also, note that a nullness checker can be sound even if it does not issue errors for some cases of jspecify_nullness_mismatch or jspecify_nullness_not_enough_information!)

  • jspecify_nullness_mismatch

  • jspecify_nullness_not_enough_information: for nullness violations that involve unspecified nullness.

TODO: Consider additional features:

  • multiline comments
  • other locations for comments
  • multiple findings per line/comment
  • comments that apply to larger ranges -- possibly to syntax elements (like statements) rather than lines
  • comments that apply only to a particular part of the line

Directory structure

See JSpecify: test-data format: Directory structure. TODO(#134): Inline that here if Tagir can sign the CLA and contribute it.

Additionally:

Fully qualified class names must be unique across all directories.

This permits all files to be compiled in a single tool invocation.

TODO: Consider requiring that all individual-file samples be in the top-level directory.

Each file must contain a single top-level class. TODO(#133): Consider relaxing this.

TODO: Consider requiring a file's path to match its package and class:

  • individual-file samples: Foo.java for Foo

  • full-directory samples: sampleFoo/Foo.java for Foo, sampleFoo/bar/Foo.java for bar.Foo

  • We may need additional accommodations for JPMS support to demonstrate module-level defaulting.

Restrictions

Files must be UTF-8 encoded.

Files must contain only printable ASCII characters and \n.

Files must be compatible with Java 8. TODO(#131): Decide how to label files that require a higher version so that we can allow them. (But still encourage sticking to Java 8 except for tests that specifically exercise newer features.)

Files must compile without error using stock javac.

Files must not depend on any classes other than the JSpecify annotations. This includes the Java platform APIs. Exception: Files may use java.lang.Object, but they still must not use its methods.

For example, files may use Object as a bound, parameter, or return type.

Files should avoid depending on the presence of absence of “smart” checker features, such as:

  • looking inside the body of a method to determine what parameters it dereferences or what it returns

    • To that end, prefer abstract methods when practical.
  • flow-sensitive typing

We also encourage writing files that demonstrate individual behaviors in isolation. For example, we encourage writing files to minimize how much they rely on type inference -- except, of course, for any files explicitly intended to demonstrate type inference.

More TODOs

TODO: Consider how to map between samples and related GitHub issues (comments, filenames?).