| plugins { |
| id 'java-library' |
| } |
| |
| ext { |
| annotatedJdkHome = '../../jdk' |
| } |
| sourceSets { |
| main { |
| resources { |
| // Stub files, message.properties, etc. |
| srcDirs += ['src/main/java', "${buildDir}/generated/resources"] |
| } |
| } |
| testannotations |
| } |
| |
| sourcesJar { |
| // The resources duplicate content from the src directory. |
| duplicatesStrategy = DuplicatesStrategy.EXCLUDE |
| } |
| |
| def versions = [ |
| autoValue : "1.7.4", |
| lombok : "1.18.20", |
| ] |
| |
| |
| dependencies { |
| api project(':javacutil') |
| api project(':dataflow') |
| api files("${stubparserJar}") |
| // AFU is an "includedBuild" imported in checker-framework/settings.gradle, so the version number doesn't matter. |
| // https://docs.gradle.org/current/userguide/composite_builds.html#settings_defined_composite |
| api('org.checkerframework:annotation-file-utilities:*') { |
| exclude group: 'com.google.errorprone', module: 'javac' |
| } |
| api project(':checker-qual') |
| |
| // External dependencies: |
| // If you add an external dependency, you must shadow its packages. |
| // See the comment in ../build.gradle in the shadowJar block. |
| implementation 'org.plumelib:plume-util:1.5.3' |
| implementation 'org.plumelib:reflection-util:1.0.3' |
| implementation 'io.github.classgraph:classgraph:4.8.105' |
| |
| // TODO: it's a bug that annotatedlib:guava requires the error_prone_annotations dependency. |
| // Update the next two version numbers in tandem. Get the Error Prone version from the "compile |
| // dependencies" section of https://mvnrepository.com/artifact/com.google.guava/guava/28.2-jre . |
| // (It isn't at https://mvnrepository.com/artifact/org.checkerframework.annotatedlib/guava/28.2-jre, which is the bug.) |
| implementation 'com.google.errorprone:error_prone_annotations:2.7.1' |
| implementation ('org.checkerframework.annotatedlib:guava:30.1.1-jre') { |
| // So long as Guava only uses annotations from checker-qual, excluding it should not cause problems. |
| exclude group: 'org.checkerframework' |
| } |
| |
| testImplementation group: 'junit', name: 'junit', version: '4.13.2' |
| testImplementation project(':framework-test') |
| testImplementation sourceSets.testannotations.output |
| |
| // AutoValue support in Returns Receiver Checker |
| testImplementation "com.google.auto.value:auto-value-annotations:${versions.autoValue}" |
| testImplementation "com.google.auto.value:auto-value:${versions.autoValue}" |
| |
| // Lombok support in Returns Receiver Checker |
| testImplementation "org.projectlombok:lombok:${versions.lombok}" |
| } |
| |
| task cloneTypetoolsJdk() { |
| description 'Obtain or update the annotated JDK.' |
| doLast { |
| if (file(annotatedJdkHome).exists()) { |
| exec { |
| workingDir annotatedJdkHome |
| executable 'git' |
| args = ['pull', '-q'] |
| ignoreExitValue = true |
| } |
| } else { |
| println 'Cloning annotated JDK repository.' |
| exec { |
| workingDir "${annotatedJdkHome}/../" |
| executable 'git' |
| args = ['clone', '-q', '--depth', '1', 'https://github.com/typetools/jdk.git', 'jdk'] |
| } |
| } |
| } |
| } |
| |
| |
| task copyAndMinimizeAnnotatedJdkFiles(dependsOn: cloneTypetoolsJdk, group: 'Build') { |
| dependsOn ':framework:compileJava' |
| def inputDir = "${annotatedJdkHome}/src" |
| def outputDir = "${buildDir}/generated/resources/annotated-jdk/" |
| |
| description "Copy annotated JDK files to ${outputDir}. Removes private and package-private methods, method bodies, comments, etc. from the annotated JDK" |
| |
| inputs.dir file(inputDir) |
| outputs.dir file(outputDir) |
| |
| doLast { |
| FileTree tree = fileTree(dir: inputDir) |
| SortedSet<String> annotatedForFiles = new TreeSet<>(); |
| tree.visit { FileVisitDetails fvd -> |
| if (!fvd.file.isDirectory() && fvd.file.name.matches(".*\\.java") |
| && !fvd.file.path.contains("org/checkerframework")) { |
| fvd.getFile().readLines().any { line -> |
| if (line.contains("@AnnotatedFor") || line.contains("org.checkerframework")) { |
| annotatedForFiles.add(fvd.file.absolutePath) |
| return true; |
| } |
| } |
| } |
| } |
| String absolutejdkHome = file(annotatedJdkHome).absolutePath |
| int jdkDirStringSize = absolutejdkHome.size() |
| copy { |
| from(annotatedJdkHome) |
| into(outputDir) |
| for (String filename : annotatedForFiles) { |
| include filename.substring(jdkDirStringSize) |
| } |
| } |
| javaexec { |
| classpath = sourceSets.main.runtimeClasspath |
| |
| main = 'org.checkerframework.framework.stub.JavaStubifier' |
| args outputDir |
| } |
| } |
| } |
| |
| processResources.dependsOn(copyAndMinimizeAnnotatedJdkFiles) |
| |
| task checkDependencies(dependsOn: ':maybeCloneAndBuildDependencies') { |
| doLast { |
| if (!file(stubparserJar).exists()) { |
| throw new GradleException("${stubparserJar} does not exist. Try running './gradlew cloneAndBuildDependencies'") |
| } |
| } |
| } |
| |
| compileJava.dependsOn(checkDependencies) |
| |
| task allSourcesJar(type: Jar, group: 'Build') { |
| description 'Creates a sources jar that includes sources for all Checker Framework classes in framework.jar' |
| destinationDirectory = file("${projectDir}/dist") |
| archiveFileName = "framework-source.jar" |
| from (project(':framework').sourceSets.main.java, |
| project(':dataflow').sourceSets.main.allJava, |
| project(':javacutil').sourceSets.main.allJava) |
| } |
| |
| task allJavadocJar(type: Jar, group: 'Build') { |
| description 'Creates javadoc jar include Javadoc for all of the framework' |
| dependsOn rootProject.tasks.allJavadoc |
| destinationDirectory = file("${projectDir}/dist") |
| archiveFileName = "framework-javadoc.jar" |
| from (project(':framework').tasks.javadoc.destinationDir, |
| project(':dataflow').tasks.javadoc.destinationDir, |
| project(':javacutil').tasks.javadoc.destinationDir) |
| } |
| |
| shadowJar { |
| description 'Creates the "fat" framework.jar in dist' |
| destinationDirectory = file("${projectDir}/dist") |
| archiveFileName = "framework.jar" |
| manifest { |
| attributes('Automatic-Module-Name': "org.checkerframework.framework") |
| } |
| } |
| |
| createCheckTypeTask(project.name, "CompilerMessages", |
| 'org.checkerframework.checker.compilermsgs.CompilerMessagesChecker') |
| checkCompilerMessages { |
| options.compilerArgs += [ |
| '-Apropfiles=' + sourceSets.main.resources.filter { file -> file.name.equals('messages.properties') }.asPath |
| ] |
| } |
| |
| task loaderTests(dependsOn: 'shadowJar', group: 'Verification') { |
| description 'Run tests for the annotation class loader' |
| dependsOn(compileTestJava) |
| // TODO: this dependency on checker is a bit ugly. |
| dependsOn project(':checker-qual').tasks.jar |
| dependsOn project(':checker').tasks.assemble |
| doLast { |
| exec { |
| executable 'make' |
| args = ['-C', "tests/annotationclassloader/", "all"] |
| } |
| } |
| } |
| |
| clean { |
| delete("tests/returnsreceiverdelomboked") |
| delete('dist') |
| } |
| |
| |
| task delombok { |
| description 'Delomboks the source code tree in tests/returnsreceiverlombok' |
| |
| def srcDelomboked = 'tests/returnsreceiverdelomboked' |
| def srcJava = 'tests/returnsreceiverlombok' |
| |
| inputs.files file(srcJava) |
| outputs.dir file(srcDelomboked) |
| |
| // This dependency is required to ensure the checker-qual jar exists, |
| // to prevent lombok from emitting "cannot find symbol" errors for @This |
| // annotations in the test input code. |
| dependsOn project(':checker-qual').tasks.jar |
| |
| doLast { |
| def collection = files(configurations.testCompileClasspath) |
| ant.taskdef(name: 'delombok', classname: 'lombok.delombok.ant.Tasks$Delombok', |
| classpath: collection.asPath) |
| ant.delombok(from: srcJava, to: srcDelomboked, classpath: collection.asPath) |
| } |
| } |
| |
| tasks.test.dependsOn("delombok") |