Skip to content

Commit d8b44d0

Browse files
committed
HHH-16515 - Add @nullable annotations to org.hibernate.spi
Signed-off-by: Jan Schatteman <[email protected]> Correction to gradle/java-module.gradle for the checkerframework Co-authored-by: Christian Beikov <[email protected]> Add @nullable annotations to org.hibernate.spi
1 parent 3543186 commit d8b44d0

File tree

5 files changed

+50
-35
lines changed

5 files changed

+50
-35
lines changed

gradle/java-module.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ checkerFramework {
524524
extraJavacArgs = [
525525
'-AsuppressWarnings=initialization',
526526
"-Astubs=${project.rootDir}/checkerstubs",
527-
'-AonlyDefs=^org\\.hibernate\\.jpamodelgen\\.'
527+
'-AonlyDefs=^org\\.hibernate\\.(jpamodelgen|spi)\\.'
528528
]
529529
}
530530

hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import org.hibernate.internal.util.collections.ArrayHelper;
2121
import org.hibernate.loader.internal.AliasConstantsHelper;
2222

23+
import org.checkerframework.checker.nullness.qual.Nullable;
24+
2325
public final class StringHelper {
2426

2527
private static final int ALIAS_TRUNCATE_LENGTH = 10;
@@ -825,7 +827,7 @@ public static String[] unquote(final String[] names, final Dialect dialect) {
825827
}
826828
}
827829

828-
public static String nullIfEmpty(String value) {
830+
public static String nullIfEmpty(@Nullable String value) {
829831
return isEmpty( value ) ? null : value;
830832
}
831833

hibernate-core/src/main/java/org/hibernate/spi/DotIdentifierSequence.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import java.util.ArrayList;
1010
import java.util.List;
1111

12-
import org.hibernate.metamodel.mapping.SelectablePath;
12+
import org.hibernate.internal.util.NullnessUtil;
13+
14+
import org.checkerframework.checker.nullness.qual.Nullable;
1315

1416
/**
1517
* A compound name.
@@ -26,7 +28,7 @@ public interface DotIdentifierSequence {
2628
* Given the sequence {@code a.b.c}, returns the sequence
2729
* {@code a.b}.
2830
*/
29-
DotIdentifierSequence getParent();
31+
@Nullable DotIdentifierSequence getParent();
3032

3133
/**
3234
* The name of this leaf sequence part.
@@ -64,8 +66,9 @@ default DotIdentifierSequence[] getParts() {
6466
}
6567

6668
private void parts(List<DotIdentifierSequence> list) {
67-
if ( getParent() != null ) {
68-
getParent().parts( list );
69+
DotIdentifierSequence parent = getParent();
70+
if ( parent != null ) {
71+
parent.parts( list );
6972
}
7073
list.add( this );
7174
}

hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
import org.hibernate.Incubating;
1313
import org.hibernate.internal.util.StringHelper;
1414

15+
import org.checkerframework.checker.nullness.qual.Nullable;
16+
17+
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
18+
1519
/**
1620
* A compound name where the root path element is an entity name or a collection role
1721
* and each the path sub-path from the root references a domain or mapping model part
@@ -23,9 +27,9 @@
2327
public class NavigablePath implements DotIdentifierSequence, Serializable {
2428
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
2529

26-
private final NavigablePath parent;
30+
private final @Nullable NavigablePath parent;
2731
private final String localName;
28-
private final String alias;
32+
private final @Nullable String alias;
2933
private final String identifierForTableGroup;
3034
private final FullPathCalculator fullPathCalculator;
3135
private final int hashCode;
@@ -34,7 +38,7 @@ public NavigablePath(String localName) {
3438
this( localName, null );
3539
}
3640

37-
public NavigablePath(String rootName, String alias) {
41+
public NavigablePath(String rootName, @Nullable String alias) {
3842
this.parent = null;
3943
this.alias = alias = StringHelper.nullIfEmpty( alias );
4044
this.localName = rootName;
@@ -49,7 +53,7 @@ public NavigablePath(NavigablePath parent, String navigableName) {
4953
this( parent, navigableName, null );
5054
}
5155

52-
public NavigablePath(NavigablePath parent, String localName, String alias) {
56+
public NavigablePath(NavigablePath parent, String localName, @Nullable String alias) {
5357
assert parent != null;
5458

5559
this.parent = parent;
@@ -79,9 +83,9 @@ public NavigablePath(NavigablePath parent, String localName, String alias) {
7983
}
8084

8185
public NavigablePath(
82-
NavigablePath parent,
86+
@Nullable NavigablePath parent,
8387
String localName,
84-
String alias,
88+
@Nullable String alias,
8589
String identifierForTableGroup,
8690
FullPathCalculator fullPathCalculator,
8791
int hashCode) {
@@ -94,7 +98,7 @@ public NavigablePath(
9498
}
9599

96100
@Override
97-
public NavigablePath getParent() {
101+
public @Nullable NavigablePath getParent() {
98102
return parent instanceof TreatedNavigablePath ? parent.getParent() : parent;
99103
}
100104

@@ -103,7 +107,7 @@ public String getLocalName() {
103107
return localName;
104108
}
105109

106-
public String getAlias() {
110+
public @Nullable String getAlias() {
107111
return alias;
108112
}
109113

@@ -121,7 +125,7 @@ public int hashCode() {
121125
}
122126

123127
@Override
124-
public boolean equals(Object other) {
128+
public boolean equals(@Nullable Object other) {
125129
if ( this == other ) {
126130
return true;
127131
}
@@ -175,14 +179,14 @@ public NavigablePath treatAs(String entityName, String alias) {
175179
return new TreatedNavigablePath( this, entityName, alias );
176180
}
177181

178-
public NavigablePath getRealParent() {
182+
public @Nullable NavigablePath getRealParent() {
179183
return parent;
180184
}
181185

182186
/**
183187
* Determine whether this path is part of the given path's parent
184188
*/
185-
public boolean isParent(NavigablePath navigablePath) {
189+
public boolean isParent(@Nullable NavigablePath navigablePath) {
186190
while ( navigablePath != null ) {
187191
if ( this.equals( navigablePath.getParent() ) ) {
188192
return true;
@@ -195,14 +199,15 @@ public boolean isParent(NavigablePath navigablePath) {
195199
/**
196200
* Determine whether the given path is a suffix of this path
197201
*/
198-
public boolean isSuffix(DotIdentifierSequence dotIdentifierSequence) {
202+
public boolean isSuffix(@Nullable DotIdentifierSequence dotIdentifierSequence) {
199203
if ( dotIdentifierSequence == null ) {
200204
return true;
201205
}
202206
if ( !localNamesMatch( dotIdentifierSequence ) ) {
203207
return false;
204208
}
205-
return getParent() != null && getParent().isSuffix( dotIdentifierSequence.getParent() );
209+
NavigablePath parent = getParent();
210+
return parent != null && parent.isSuffix( dotIdentifierSequence.getParent() );
206211
}
207212

208213
/**
@@ -216,23 +221,24 @@ public boolean isSuffix(DotIdentifierSequence dotIdentifierSequence) {
216221
* or null if the NavigablePath does not contain the suffix.
217222
*
218223
*/
219-
public NavigablePath trimSuffix(DotIdentifierSequence suffix) {
224+
public @Nullable NavigablePath trimSuffix(@Nullable DotIdentifierSequence suffix) {
220225
if ( suffix == null ) {
221226
return this;
222227
}
223228
if ( !getLocalName().equals( suffix.getLocalName() ) ) {
224229
return null;
225230
}
226-
if ( getParent() != null ) {
227-
return getParent().trimSuffix( suffix.getParent() );
231+
NavigablePath parent = getParent();
232+
if ( parent != null ) {
233+
return parent.trimSuffix( suffix.getParent() );
228234
}
229235
return null;
230236
}
231237

232238
/**
233239
* Determine whether this path is part of the given path's parent
234240
*/
235-
public boolean isParentOrEqual(NavigablePath navigablePath) {
241+
public boolean isParentOrEqual(@Nullable NavigablePath navigablePath) {
236242
while ( navigablePath != null ) {
237243
if ( this.equals( navigablePath ) ) {
238244
return true;
@@ -242,15 +248,15 @@ public boolean isParentOrEqual(NavigablePath navigablePath) {
242248
return false;
243249
}
244250

245-
public boolean pathsMatch(NavigablePath p) {
251+
public boolean pathsMatch(@Nullable NavigablePath p) {
246252
return this == p || p != null && localName.equals( p.localName )
247253
&& ( parent == null ? p.parent == null && Objects.equals( alias, p.alias ) : parent.pathsMatch( p.parent ) );
248254
}
249255

250256
/**
251257
* Ignores aliases in the resulting String
252258
*/
253-
public String relativize(NavigablePath base) {
259+
public @Nullable String relativize(NavigablePath base) {
254260
// e.g.
255261
// - base = Root.sub
256262
// - this = Root.sub.stuff
@@ -284,7 +290,7 @@ public void collectPath(String path) {
284290
buffer.append( path );
285291
}
286292

287-
public String resolve() {
293+
public @Nullable String resolve() {
288294
if ( buffer == null ) {
289295
// Return an empty string instead of null in case the two navigable paths are equal
290296
return matchedBase ? "" : null;
@@ -323,24 +329,24 @@ public String toString() {
323329
*/
324330
@FunctionalInterface
325331
protected interface FullPathCalculator extends Serializable {
326-
String calculateFullPath(NavigablePath parent, String localName, String alias);
332+
String calculateFullPath(@Nullable NavigablePath parent, String localName, @Nullable String alias);
327333
}
328334

329335
/**
330336
* The pattern used for root NavigablePaths
331337
*/
332-
protected static String calculateRootFullPath(NavigablePath parent, String rootName, String alias) {
338+
protected static String calculateRootFullPath(@Nullable NavigablePath parent, String rootName, @Nullable String alias) {
333339
assert parent == null;
334340
return alias == null ? rootName : rootName + "(" + alias + ")";
335341
}
336342

337343
/**
338344
* The normal pattern used for the "full path"
339345
*/
340-
private static String calculateNormalFullPath(NavigablePath parent, String localName, String alias) {
346+
private static String calculateNormalFullPath(@Nullable NavigablePath parent, String localName, @Nullable String alias) {
341347
assert parent != null;
342348

343-
final String parentFullPath = parent.getFullPath();
349+
final String parentFullPath = castNonNull( parent ).getFullPath();
344350
final String baseFullPath = StringHelper.isEmpty( parentFullPath )
345351
? localName
346352
: parentFullPath + "." + localName;
@@ -350,7 +356,7 @@ private static String calculateNormalFullPath(NavigablePath parent, String local
350356
/**
351357
* Pattern used for `_identifierMapper`
352358
*/
353-
protected static String calculateIdMapperFullPath(NavigablePath parent, String localName, String alias) {
359+
protected static String calculateIdMapperFullPath(@Nullable NavigablePath parent, String localName, @Nullable String alias) {
354360
return parent != null ? parent.getFullPath() : "";
355361
}
356362
}

hibernate-core/src/main/java/org/hibernate/spi/TreatedNavigablePath.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
import org.hibernate.Incubating;
1010

11+
import org.checkerframework.checker.nullness.qual.Nullable;
12+
13+
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
14+
1115
/**
1216
* An implementation of {@link NavigablePath} with special handling for treated paths.
1317
*
@@ -20,7 +24,7 @@ public TreatedNavigablePath(NavigablePath parent, String entityTypeName) {
2024
this( parent, entityTypeName, null );
2125
}
2226

23-
public TreatedNavigablePath(NavigablePath parent, String entityTypeName, String alias) {
27+
public TreatedNavigablePath(NavigablePath parent, String entityTypeName, @Nullable String alias) {
2428
super(
2529
parent,
2630
"#" + entityTypeName,
@@ -32,20 +36,20 @@ public TreatedNavigablePath(NavigablePath parent, String entityTypeName, String
3236
assert !( parent instanceof TreatedNavigablePath );
3337
}
3438

35-
protected static String calculateTreatedFullPath(NavigablePath parent, String localName, String alias) {
39+
protected static String calculateTreatedFullPath(@Nullable NavigablePath parent, String localName, @Nullable String alias) {
3640
return alias == null
3741
? "treat(" + parent + " as " + localName + ")"
3842
: "treat(" + parent + " as " + localName + ")(" + alias + ")";
3943
}
4044

4145
@Override
4246
public NavigablePath treatAs(String entityName) {
43-
return new TreatedNavigablePath( getRealParent(), entityName );
47+
return new TreatedNavigablePath( castNonNull( getRealParent() ), entityName );
4448
}
4549

4650
@Override
4751
public NavigablePath treatAs(String entityName, String alias) {
48-
return new TreatedNavigablePath( getRealParent(), entityName, alias );
52+
return new TreatedNavigablePath( castNonNull( getRealParent() ), entityName, alias );
4953
}
5054

5155
// @Override

0 commit comments

Comments
 (0)