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

Add command line option to skip specific library models. #741

Merged
merged 4 commits into from
Mar 6, 2023

Conversation

lazaroclapp
Copy link
Collaborator

This PR adds the CLI option -XepOpt:NullAway:IgnoreLibraryModelsFor which takes a list of methods, given as fully qualified class name + method simple name (i.e. independent of argument types).

Methods matching this list will be skipped when loading library models (from any implementation of the LibraryModels's @AutoService as well as our included models). This can be used in a per-compilation target basis to disable NullAway's library models for ease of upgrading to new versions with stricter modeling of common JDK or third-party APIs.

We considered a few alternative approaches here, but decided against:

  • Simply using another instance of LibraryModels to "invert" the models given by NullAway's default library models: This would have required no code changes, but doesn't work in all cases. If NullAway's default models make the return of method foo() @Nullable, for example, then a new model that makes the return @NonNull will break @Nullable overrides of foo(). In general, we want to go back to "optimistic assumptions" rather than just replace the library model.
  • We could have a list of methods in the LibraryModels for which to ignore previous models, and have those override any models on those methods coming from a different LibraryModels implementation. But, from the point of view of the user configuring NullAway, this is complex: they need to have an instance of custom library models in their build, and changing java plugin classpath deps on a per-target basis is more complex than changing CLI arguments (e.g. due to JVM re-use by the build system).
  • We could provide more specific disabling of library models (e.g. a specific method signature or removing only one particular kind of model from a method, such as keeping the model on the return value, but removing it from an argument, or removing a null-implies-false model or similar). We could revisit this in the future, but supporting this would make the syntax of the CLI values a lot more complex. For now, we believe just turning off all models for a given method is a sufficient degree of granularity.
  • Per-package/per-class/regex based ignore specs: See above. Avoiding complexity until we need it.

Note: If and when this lands, it needs a Wiki documentation update!

@coveralls
Copy link

coveralls commented Feb 24, 2023

Pull Request Test Coverage Report for Build #1070

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 15 unchanged lines in 3 files lost coverage.
  • Overall coverage decreased (-0.08%) to 93.066%

Files with Coverage Reduction New Missed Lines %
../nullaway/src/main/java/com/uber/nullaway/AbstractConfig.java 4 93.94%
../nullaway/src/main/java/com/uber/nullaway/ErrorProneCLIFlagsConfig.java 5 94.19%
../nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java 6 97.78%
Totals Coverage Status
Change from base Build #1069: -0.08%
Covered Lines: 5463
Relevant Lines: 5870

💛 - Coveralls

Copy link
Collaborator

@msridhar msridhar left a comment

Choose a reason for hiding this comment

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

Mostly LGTM, just one question

@@ -292,6 +294,11 @@ public boolean isContractAnnotation(String annotationName) {
return contractAnnotations.contains(annotationName);
}

@Override
public boolean isSkippedLibraryModel(String classDotMethod) {
return skippedLibraryModels.stream().anyMatch(classDotMethod::equals);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not just skippedLibraryModels.contains(classDotMethod)?

@@ -788,34 +791,61 @@ public CombinedLibraryModels(Iterable<LibraryModels> models) {
new ImmutableSetMultimap.Builder<>();
for (LibraryModels libraryModels : models) {
for (Map.Entry<MethodRef, Integer> entry : libraryModels.failIfNullParameters().entries()) {
if (shouldSkipModel(entry.getKey())) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍 Good that we just pay the cost when loading the models and not after

Copy link
Collaborator

@msridhar msridhar left a comment

Choose a reason for hiding this comment

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

@lazaroclapp I went ahead and fixed my one minor comment, so I'm approving now. I'll hold off on landing so you can make sure 7821282 looks fine first

@lazaroclapp lazaroclapp merged commit 9b6d93f into master Mar 6, 2023
msridhar added a commit to NikitaAware/Nikita-Aware-NullAway that referenced this pull request Mar 8, 2023
Serialization version 3: update method serialization to exclude type use annotations and type arguments (uber#735)

This PR updates serialization to version `3` and burns version `2`.

Changes in serialization version 3:

- Type arguments and Type use annotations are excluded from the serialized method signatures.

---
Additional context:
This PR updates method serialization to ensure only relevant information in a method signature is serialized. Previous to this PR, method signatures serialization was relying on calling  `.toString()` method, but if a parameter contains an annotation of type `@Target({TYPE_USE})` the annotation will exist in the `.toSting()` output which is not part of a method signature. This PR updates serialization to ensure exact method signature as expected is serialized.

Suggested change

suggested changes

ternary operator as a method argument

Docs: `-XepExcludedPaths` was added in 2.1.3, not 2.13 (uber#744)

Add command line option to skip specific library models. (uber#741)

This PR adds the CLI option `-XepOpt:NullAway:IgnoreLibraryModelsFor` which takes a list of methods, given as fully qualified class name + method simple name (i.e. independent of argument types).

Methods matching this list will be skipped when loading library models (from any implementation of the `LibraryModels`'s `@AutoService` as well as our included models). This can be used in a per-compilation target basis to disable NullAway's library models for ease of upgrading to new versions with stricter modeling of common JDK or third-party APIs.

We considered a few alternative approaches here, but decided against:

- Simply using another instance of `LibraryModels` to "invert" the models given by NullAway's default library models: This would have required no code changes, but doesn't work in all cases. If NullAway's default models make the return of method `foo()` `@Nullable`, for example, then a new model that makes the return `@NonNull` will break `@Nullable` overrides of `foo()`. In general, we want to go back to "optimistic assumptions" rather than just replace the library model.
- We could have a list of methods in the `LibraryModels` for which to ignore previous models, and have those override any models on those methods coming from a different `LibraryModels` implementation. But, from the point of view of the user configuring NullAway, this is complex: they need to have an instance of custom library models in their build, and changing java plugin classpath deps on a per-target basis is more complex than changing CLI arguments (e.g. due to JVM re-use by the build system).
- We could provide more specific disabling of library models (e.g. a specific method signature or removing only one particular kind of model from a method, such as keeping the model on the return value, but removing it from an argument, or removing a null-implies-false model or similar). We could revisit this in the future, but supporting this would make the syntax of the CLI values a lot more complex. For now, we believe just turning off all models for a given method is a sufficient degree of granularity.
- Per-package/per-class/regex based ignore specs: See above. Avoiding complexity until we need it.

Note: If and when this lands, it needs a Wiki documentation update!

---------
Co-authored-by: Manu Sridharan <msridhar@gmail.com>
@msridhar msridhar deleted the lazaro_ommit_library_models branch March 9, 2023 17:06
msridhar added a commit to msridhar/NullAway that referenced this pull request Jul 18, 2023
msridhar added a commit to msridhar/NullAway that referenced this pull request Jul 18, 2023
msridhar added a commit to msridhar/NullAway that referenced this pull request Jul 19, 2023
msridhar added a commit to msridhar/NullAway that referenced this pull request Jul 19, 2023
msridhar added a commit to msridhar/NullAway that referenced this pull request Jul 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants