-
Notifications
You must be signed in to change notification settings - Fork 299
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
External Library Models Integration #922
Changes from all commits
1d48e6e
b0631cb
e5353d1
ea7d117
e9a06dc
19b020b
31f569c
a26f856
a863363
ee56362
3806c80
32f0990
3dedc77
07586ae
4b7891e
10c36e3
36b5a21
a6c8204
0c2cd44
ac14c99
2dbc283
32e80d5
2b637f1
888c1b2
fb81869
e889dc3
26efa96
cbe7bf5
600164c
d1fed93
db993b8
09c0f4c
161c6ac
27ebcc9
5ee2428
8c442f7
609f2e5
fb83aff
629ec5b
5190597
fd7d546
f213d82
1137aa9
6e0ef33
41bc90f
26c4907
dc0618a
5fa73da
14e39b6
f390cd1
ad44788
2a1c2da
8f86b36
35b988c
c1fe36b
d301e28
439ca14
e2a9c60
a072bbd
75785fa
80be0d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright (C) 2024. Uber Technologies | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
plugins { | ||
id "java-library" | ||
id "com.github.johnrengelman.shadow" | ||
} | ||
|
||
jar{ | ||
manifest { | ||
attributes('Main-Class':'com.uber.nullaway.libmodel.LibraryModelGeneratorCLI') | ||
} | ||
// add this classifier so that the output file for the jar task differs from | ||
// the output file for the shadowJar task (otherwise they overwrite each other's | ||
// outputs, forcing the tasks to always re-run) | ||
archiveClassifier = "nonshadow" | ||
} | ||
|
||
shadowJar { | ||
mergeServiceFiles() | ||
configurations = [ | ||
project.configurations.runtimeClasspath | ||
] | ||
archiveClassifier = "" | ||
} | ||
shadowJar.dependsOn jar | ||
assemble.dependsOn shadowJar | ||
|
||
dependencies { | ||
implementation project(":library-model:library-model-generator") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright (c) 2024 Uber Technologies, Inc. | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
package com.uber.nullaway.libmodel; | ||
|
||
/** | ||
* A CLI tool for invoking the process for {@link LibraryModelGenerator} which generates astubx | ||
* file(s) from a directory containing annotated source code to be used as external library models. | ||
*/ | ||
public class LibraryModelGeneratorCLI { | ||
/** | ||
* This is the main method of the cli tool. It parses the source files within a specified | ||
* directory, obtains meaningful Nullability annotation information and writes it into an astubx | ||
* file. | ||
* | ||
* @param args Command line arguments for the directory containing source files and the output | ||
* directory. | ||
*/ | ||
public static void main(String[] args) { | ||
if (args.length != 2) { | ||
System.out.println( | ||
"Incorrect number of command line arguments. Required arguments: <inputSourceDirectory> <outputDirectory>"); | ||
return; | ||
} | ||
LibraryModelGenerator libraryModelGenerator = new LibraryModelGenerator(); | ||
libraryModelGenerator.generateAstubxForLibraryModels(args[0], args[1]); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright (C) 2024. Uber Technologies | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
plugins { | ||
id "java-library" | ||
id "nullaway.java-test-conventions" | ||
} | ||
|
||
dependencies { | ||
testImplementation project(":nullaway") | ||
testImplementation project(":library-model:test-library-model-generator") | ||
testImplementation deps.test.junit4 | ||
testImplementation(deps.build.errorProneTestHelpers) { | ||
exclude group: "junit", module: "junit" | ||
} | ||
implementation deps.build.guava | ||
implementation deps.build.javaparser | ||
compileOnly deps.apt.autoValueAnnot | ||
annotationProcessor deps.apt.autoValue | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package com.uber.nullaway.libmodel; | ||
|
||
import com.google.errorprone.CompilationTestHelper; | ||
import com.uber.nullaway.NullAway; | ||
import java.util.Arrays; | ||
import org.junit.Before; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.TemporaryFolder; | ||
|
||
public class LibraryModelIntegrationTest { | ||
|
||
@Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); | ||
|
||
private CompilationTestHelper compilationHelper; | ||
|
||
@Before | ||
public void setup() { | ||
compilationHelper = CompilationTestHelper.newInstance(NullAway.class, getClass()); | ||
} | ||
|
||
@Test | ||
public void libraryModelNullableReturnsTest() { | ||
compilationHelper | ||
.setArgs( | ||
Arrays.asList( | ||
"-d", | ||
temporaryFolder.getRoot().getAbsolutePath(), | ||
"-XepOpt:NullAway:AnnotatedPackages=com.uber", | ||
"-XepOpt:NullAway:JarInferEnabled=true", | ||
"-XepOpt:NullAway:JarInferUseReturnAnnotations=true")) | ||
Comment on lines
+30
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @yuxincs that overloading the meaning of the It can certainly be a follow up PR, but I'd be in favor of rethinking these CLI flags. Maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am in favor of changing these, but maybe in a follow-up PR. I don't think we need to go as far as keeping the old flag but deprecating it, as long as we document properly in release notes. But we should probably check as to what this breaks (if anything) internally at Uber. @akulk022 can you open an issue on renaming these flags? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've created the issue #940 |
||
.addSourceLines( | ||
"Test.java", | ||
"package com.uber;", | ||
"import com.uber.nullaway.libmodel.AnnotationExample;", | ||
"class Test {", | ||
" static AnnotationExample annotationExample = new AnnotationExample();", | ||
" static void test(String value){", | ||
" }", | ||
" static void testPositive() {", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'annotationExample.makeUpperCase(\"nullaway\")'", | ||
" test(annotationExample.makeUpperCase(\"nullaway\"));", | ||
" }", | ||
" static void testNegative() {", | ||
" test(annotationExample.nullReturn());", | ||
" }", | ||
"}") | ||
.doTest(); | ||
} | ||
|
||
@Test | ||
public void libraryModelNullableReturnsArrayTest() { | ||
compilationHelper | ||
.setArgs( | ||
Arrays.asList( | ||
"-d", | ||
temporaryFolder.getRoot().getAbsolutePath(), | ||
"-XepOpt:NullAway:AnnotatedPackages=com.uber", | ||
"-XepOpt:NullAway:JarInferEnabled=true", | ||
"-XepOpt:NullAway:JarInferUseReturnAnnotations=true")) | ||
.addSourceLines( | ||
"Test.java", | ||
"package com.uber;", | ||
"import com.uber.nullaway.libmodel.AnnotationExample;", | ||
"class Test {", | ||
" static AnnotationExample annotationExample = new AnnotationExample();", | ||
" static void test(Integer[] value){", | ||
" }", | ||
" static void testPositive() {", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'annotationExample.generateIntArray(7)'", | ||
" test(annotationExample.generateIntArray(7));", | ||
Comment on lines
+70
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fun! This wasn't possible in my version of the Edit: Ah, never mind, it uses the same position of annotation as the case above, we haven't introduced yet a way to annotate both the elements of an array and the array itself, correct? But this parses the annotation in the correct/JSpecify location. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, you are correct. jspecify/jdk puts the annotation in the right spot, so if you parse it the incorrect way you get incorrect specs :-) You're right that we don't yet support annotations in both positions. Do you think this needs a code comment @lazaroclapp? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't hurt, but I also think that behavior will get less and less surprising with time as the "JSpecify way" becomes the default overall for NullAway and arrays (at least for type-use annotations). |
||
" }", | ||
"}") | ||
.doTest(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a test case without the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, may I suggest a case with a model adding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lazaroclapp We have not added the functionality for processing the annotations on method parameters in this PR so a test case with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also @lazaroclapp I don't think supporting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There isn't a chance that specific classes will be |
||
|
||
@Test | ||
public void libraryModelWithoutJarInferEnabledTest() { | ||
compilationHelper | ||
.setArgs( | ||
Arrays.asList( | ||
"-d", | ||
temporaryFolder.getRoot().getAbsolutePath(), | ||
"-XepOpt:NullAway:AnnotatedPackages=com.uber")) | ||
.addSourceLines( | ||
"Test.java", | ||
"package com.uber;", | ||
"import com.uber.nullaway.libmodel.AnnotationExample;", | ||
"class Test {", | ||
" static AnnotationExample annotationExample = new AnnotationExample();", | ||
" static void test(String value){", | ||
" }", | ||
" static void testNegative() {", | ||
" // Since the JarInferEnabled and JarInferUseReturnAnnotations flags are not set, we don't get an error here", | ||
" test(annotationExample.makeUpperCase(\"nullaway\"));", | ||
" }", | ||
"}") | ||
.doTest(); | ||
} | ||
|
||
@Test | ||
public void libraryModelInnerClassNullableReturnsTest() { | ||
compilationHelper | ||
.setArgs( | ||
Arrays.asList( | ||
"-d", | ||
temporaryFolder.getRoot().getAbsolutePath(), | ||
"-XepOpt:NullAway:AnnotatedPackages=com.uber", | ||
"-XepOpt:NullAway:JarInferEnabled=true", | ||
"-XepOpt:NullAway:JarInferUseReturnAnnotations=true")) | ||
.addSourceLines( | ||
"Test.java", | ||
"package com.uber;", | ||
"import com.uber.nullaway.libmodel.AnnotationExample;", | ||
"class Test {", | ||
" static AnnotationExample.InnerExample innerExample = new AnnotationExample.InnerExample();", | ||
" static void test(String value){", | ||
" }", | ||
" static void testPositive() {", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'innerExample.returnNull()'", | ||
" test(innerExample.returnNull());", | ||
" }", | ||
"}") | ||
.doTest(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright (C) 2024. Uber Technologies | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
plugins { | ||
id 'java-library' | ||
id 'nullaway.java-test-conventions' | ||
} | ||
|
||
dependencies { | ||
implementation deps.build.guava | ||
implementation deps.build.javaparser | ||
compileOnly deps.apt.autoValueAnnot | ||
annotationProcessor deps.apt.autoValue | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check the number of args and print a basic usage message? (Not sure if we do that for JarInfer, and I don't think we need a full argument parser here yet, a check on the length of
args
would suffice for now)