Skip to content
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

feat: add nullness annotations on public API (WIP) #1009

Merged
merged 31 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
11c473e
feat: add nullness annotations on public API (WIP)
greyhairredbear Jul 30, 2024
4e266e9
feat: add nullness annotations on public API (WIP)
greyhairredbear Aug 6, 2024
a00c70b
fix: imports once more
greyhairredbear Aug 6, 2024
876cde6
feat: add nullability annotations to score package and children (WIP)
greyhairredbear Aug 13, 2024
184ca48
feat: add nullability annotations to domain package and children (WIP)
greyhairredbear Aug 13, 2024
d8714e2
feat: add nullability annotations to function package and children (WIP)
greyhairredbear Aug 14, 2024
1023fae
feat: add nullability annotations to impl of domain and score.calcula…
greyhairredbear Aug 14, 2024
552f47d
feat: add nullability annotations to score.analysis and impl of score…
greyhairredbear Aug 14, 2024
f7cedc7
chore: add todos regarding null warnings
greyhairredbear Aug 14, 2024
251dfc8
feat: add nullability annotations to Score implementations (wip)
greyhairredbear Aug 14, 2024
c939cfd
feat: add nullability annotations to score.buildin
greyhairredbear Aug 22, 2024
c26313e
feat: add nullability annotations to stream and stream.bi packages
greyhairredbear Oct 3, 2024
72b2597
feat: add nullability annotations to stream.common package
greyhairredbear Oct 3, 2024
3c19da2
feat: add missing nullability annotations to stream package
greyhairredbear Oct 3, 2024
9c05383
feat: add missing nullability annotations to stream.uni package (WIP)
greyhairredbear Oct 3, 2024
72bc786
feat: add missing nullability annotations to stream.uni package
greyhairredbear Oct 9, 2024
3c3ae45
feat: add missing nullability annotations to expand method
greyhairredbear Oct 16, 2024
a575ad9
feat: add missing nullability annotations to TriConstraintBuilder and…
greyhairredbear Oct 16, 2024
b39bb7d
feat: add missing nullability annotations to TriConstraintStream (WIP)
greyhairredbear Oct 16, 2024
92ada2c
feat: add missing nullability annotations to TriConstraintStream (WIP)
greyhairredbear Oct 17, 2024
fdfc929
feat: add missing nullability annotations to TriConstraintStream
greyhairredbear Oct 17, 2024
64571f6
fix: remove duplicate annotation
greyhairredbear Oct 17, 2024
4f72427
feat: add missing nullability annotations to stream.quad (WIP)
greyhairredbear Oct 17, 2024
c0e5447
chore: add missing nullability annotations to RecommendedAssignment a…
greyhairredbear Oct 20, 2024
aafe5c4
chore: review-related changes
greyhairredbear Oct 21, 2024
93cfcad
fix: format
greyhairredbear Oct 21, 2024
74536a5
fix: correct name Constraints -> defineConstraints
greyhairredbear Oct 22, 2024
525fe3a
fix: add undeclared dependencies
greyhairredbear Oct 22, 2024
e5bc16b
chore: default values for BendableScore private ctor
greyhairredbear Oct 22, 2024
abc5b85
fix: ignore revapi false positives
greyhairredbear Oct 22, 2024
d0f9a4a
chore: resolve open TODOs
greyhairredbear Oct 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions benchmark/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<!-- standardized nullness annotations -->
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import ai.timefold.solver.core.impl.testdata.domain.TestdataValue;
import ai.timefold.solver.core.impl.testdata.util.PlannerTestUtils;

import org.jspecify.annotations.NonNull;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -321,7 +322,7 @@ void buildPlannerBenchmark() {

public static class TestdataConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
public Constraint @NonNull [] defineConstraints(@NonNull ConstraintFactory constraintFactory) {
return new Constraint[0];
}
}
Expand Down
8 changes: 8 additions & 0 deletions build/build-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<version.org.webjars.webjars-locator>0.52</version.org.webjars.webjars-locator>
<version.org.webjars.bootstrap>5.2.3</version.org.webjars.bootstrap>
<version.org.webjars.jquery>3.6.4</version.org.webjars.jquery>
<version.org.jspecify>1.0.0</version.org.jspecify>

<!-- ************************************************************************ -->
<!-- Plugins -->
Expand Down Expand Up @@ -134,6 +135,11 @@
<artifactId>jfreechart</artifactId>
<version>${version.org.jfree.jfreechart}</version>
</dependency>
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<version>${version.org.jspecify}</version>
</dependency>

<!-- ASM -->
<dependency>
Expand Down Expand Up @@ -184,6 +190,8 @@
<version>${version.org.webjars.jquery}</version>
<scope>runtime</scope>
</dependency>


</dependencies>
</dependencyManagement>

Expand Down
5 changes: 5 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- standardized nullness annotations -->
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
23 changes: 23 additions & 0 deletions core/src/build/revapi-differences.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,29 @@
"oldValue": "{\"terminationClass\", \"terminationCompositionStyle\", \"spentLimit\", \"millisecondsSpentLimit\", \"secondsSpentLimit\", \"minutesSpentLimit\", \"hoursSpentLimit\", \"daysSpentLimit\", \"unimprovedSpentLimit\", \"unimprovedMillisecondsSpentLimit\", \"unimprovedSecondsSpentLimit\", \"unimprovedMinutesSpentLimit\", \"unimprovedHoursSpentLimit\", \"unimprovedDaysSpentLimit\", \"unimprovedScoreDifferenceThreshold\", \"bestScoreLimit\", \"bestScoreFeasible\", \"stepCountLimit\", \"unimprovedStepCountLimit\", \"scoreCalculationCountLimit\", \"terminationConfigList\"}",
"newValue": "{\"terminationClass\", \"terminationCompositionStyle\", \"spentLimit\", \"millisecondsSpentLimit\", \"secondsSpentLimit\", \"minutesSpentLimit\", \"hoursSpentLimit\", \"daysSpentLimit\", \"unimprovedSpentLimit\", \"unimprovedMillisecondsSpentLimit\", \"unimprovedSecondsSpentLimit\", \"unimprovedMinutesSpentLimit\", \"unimprovedHoursSpentLimit\", \"unimprovedDaysSpentLimit\", \"unimprovedScoreDifferenceThreshold\", \"bestScoreLimit\", \"bestScoreFeasible\", \"stepCountLimit\", \"unimprovedStepCountLimit\", \"scoreCalculationCountLimit\", \"moveCountLimit\", \"terminationConfigList\"}",
"justification": "Add new termination configuration"
},
{
"ignore": true,
"code": "java.method.parameterTypeParameterChanged",
"old": "parameter <Temporal_ extends java.time.temporal.Temporal & java.lang.Comparable<? super Temporal_>> ai.timefold.solver.core.api.domain.valuerange.CountableValueRange<Temporal_> ai.timefold.solver.core.api.domain.valuerange.ValueRangeFactory::createTemporalValueRange(===Temporal_===, Temporal_, long, java.time.temporal.TemporalUnit)",
"new": "parameter <Temporal_ extends java.time.temporal.Temporal & java.lang.Comparable<? super Temporal_>> ai.timefold.solver.core.api.domain.valuerange.CountableValueRange<Temporal_> ai.timefold.solver.core.api.domain.valuerange.ValueRangeFactory::createTemporalValueRange(===Temporal_===, Temporal_, long, java.time.temporal.TemporalUnit)",
"parameterIndex": "0",
"justification": "False positive after addition of @NonNull annotation"
},
{
"ignore": true,
"code": "java.method.parameterTypeParameterChanged",
"old": "parameter <Temporal_ extends java.time.temporal.Temporal & java.lang.Comparable<? super Temporal_>> ai.timefold.solver.core.api.domain.valuerange.CountableValueRange<Temporal_> ai.timefold.solver.core.api.domain.valuerange.ValueRangeFactory::createTemporalValueRange(Temporal_, ===Temporal_===, long, java.time.temporal.TemporalUnit)",
"new": "parameter <Temporal_ extends java.time.temporal.Temporal & java.lang.Comparable<? super Temporal_>> ai.timefold.solver.core.api.domain.valuerange.CountableValueRange<Temporal_> ai.timefold.solver.core.api.domain.valuerange.ValueRangeFactory::createTemporalValueRange(Temporal_, ===Temporal_===, long, java.time.temporal.TemporalUnit)",
"parameterIndex": "1",
"justification": "False positive after addition of @NonNull annotation"
},
{
"ignore": true,
"code": "java.method.returnTypeTypeParametersChanged",
"old": "method Score_ ai.timefold.solver.core.api.score.constraint.ConstraintMatch<Score_ extends ai.timefold.solver.core.api.score.Score<Score_>>::getScore()",
"new": "method Score_ ai.timefold.solver.core.api.score.constraint.ConstraintMatch<Score_ extends ai.timefold.solver.core.api.score.Score<Score_>>::getScore()",
"justification": "False positive after addition of @NonNull annotation"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import ai.timefold.solver.core.api.domain.solution.PlanningSolution;

import org.jspecify.annotations.NonNull;

/**
* Decides on accepting or discarding a {@link PlanningEntity}.
* A pinned {@link PlanningEntity}'s planning variables are never changed.
Expand All @@ -13,9 +15,9 @@ public interface PinningFilter<Solution_, Entity_> {

/**
* @param solution working solution to which the entity belongs
* @param entity never null, a {@link PlanningEntity}
* @param entity a {@link PlanningEntity}
* @return true if the entity it is pinned, false if the entity is movable.
*/
boolean accept(Solution_ solution, Entity_ entity);
boolean accept(@NonNull Solution_ solution, @NonNull Entity_ entity);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import ai.timefold.solver.core.api.solver.change.ProblemChange;
import ai.timefold.solver.core.impl.domain.solution.DefaultConstraintWeightOverrides;

import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

/**
* Used to override constraint weights defined in Constraint Streams,
* e.g., in {@link UniConstraintStream#penalize(Score)}.
Expand Down Expand Up @@ -46,16 +49,17 @@ static <Score_ extends Score<Score_>> ConstraintWeightOverrides<Score_> of(Map<S
/**
* Return a constraint weight for a particular constraint.
*
* @param constraintName never null
* @return null if the constraint name is not known
*/
Score_ getConstraintWeight(String constraintName);
@Nullable
Score_ getConstraintWeight(@NonNull String constraintName);

/**
* Returns all known constraints.
*
*
* @return All constraint names for which {@link #getConstraintWeight(String)} returns a non-null value.
*/
@NonNull
Set<String> getKnownConstraintNames();

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import ai.timefold.solver.core.api.domain.solution.cloner.SolutionCloner;
import ai.timefold.solver.core.api.score.stream.ConstraintProvider;

import org.jspecify.annotations.NonNull;

/**
* Specifies that the class is a planning solution.
* A solution represents a problem and a possible solution of that problem.
Expand Down Expand Up @@ -53,9 +55,8 @@
* This feature is not supported under Quarkus.
* When using Quarkus,
* setting this to anything other than {@link AutoDiscoverMemberType#NONE} will result in a build-time exception.
*
* @return never null
*/
@NonNull
AutoDiscoverMemberType autoDiscoverMemberType() default AutoDiscoverMemberType.NONE;

/**
Expand All @@ -74,9 +75,9 @@ interface NullSolutionCloner extends SolutionCloner {

/**
* @deprecated When multi-threaded solving, ensure your domain classes use @{@link PlanningId} instead.
* @return never null
*/
@Deprecated(forRemoval = true, since = "1.10.0")
@NonNull
LookUpStrategyType lookUpStrategyType() default LookUpStrategyType.PLANNING_ID_OR_NONE;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import ai.timefold.solver.core.api.domain.solution.PlanningSolution;

import org.jspecify.annotations.NonNull;

/**
* Clones a {@link PlanningSolution} during planning.
* Used to remember the state of a good {@link PlanningSolution} so it can be recalled at a later time
Expand Down Expand Up @@ -34,9 +36,10 @@ public interface SolutionCloner<Solution_> {
* <p>
* This method is thread-safe.
*
* @param original never null, the original {@link PlanningSolution}
* @return never null, the cloned {@link PlanningSolution}
* @param original the original {@link PlanningSolution}
* @return the cloned {@link PlanningSolution}
*/
Solution_ cloneSolution(Solution_ original);
@NonNull
Solution_ cloneSolution(@NonNull Solution_ original);

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

import ai.timefold.solver.core.api.domain.variable.PlanningVariable;

import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

/**
* A {@link ValueRange} that is ending. Therefore, it has a discrete (as in non-continuous) range.
*
Expand All @@ -27,13 +30,13 @@ public interface CountableValueRange<T> extends ValueRange<T> {
* @param index always {@code <} {@link #getSize()}
* @return sometimes null (if {@link PlanningVariable#allowsUnassigned()} is true)
*/
@Nullable
T get(long index);

/**
* Select the elements in original (natural) order.
*
* @return never null
*/
@NonNull
Iterator<T> createOriginalIterator();

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import ai.timefold.solver.core.api.domain.variable.PlanningVariable;

import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

/**
* A ValueRange is a set of a values for a {@link PlanningVariable}.
* These values might be stored in memory as a {@link Collection} (usually a {@link List} or {@link Set}),
Expand All @@ -34,17 +37,17 @@ public interface ValueRange<T> {
* @param value sometimes null
* @return true if the ValueRange contains that value
*/
boolean contains(T value);
boolean contains(@Nullable T value);

/**
* Select in random order, but without shuffling the elements.
* Each element might be selected multiple times.
* Scales well because it does not require caching.
*
* @param workingRandom never null, the {@link Random} to use when any random number is needed,
* @param workingRandom the {@link Random} to use when any random number is needed,
* so runs are reproducible.
* @return never null
*/
Iterator<T> createRandomIterator(Random workingRandom);
@NonNull
Iterator<T> createRandomIterator(@NonNull Random workingRandom);

}
Loading
Loading