Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 39 additions & 21 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ext {
// The int corresponding to the major version of the current JVM.
currentRuntimeJavaVersion = majorVersionToInt(JavaVersion.current().getMajorVersion())

String useJdkVersionProp = project.getProperties().get('useJdkVersion')
String useJdkVersionProp = findProperty('useJdkVersion')
if (useJdkVersionProp == null) {
// If the property is not given, use the same version as the runtime.
useJdkVersionInt = currentRuntimeJavaVersion
Expand Down Expand Up @@ -176,6 +176,18 @@ spotlessPredeclare {
}

allprojects { currentProj ->
// Explicitly propagate root-level ext properties so subproject build scripts
// can access them directly without triggering the deprecated implicit-parent-lookup.
ext {
currentRuntimeJavaVersion = rootProject.ext.currentRuntimeJavaVersion
useJdkVersionInt = rootProject.ext.useJdkVersionInt
isJava8 = rootProject.ext.isJava8
skipDelombok = rootProject.ext.skipDelombok
versions = rootProject.ext.versions
javadocMemberLevel = rootProject.ext.javadocMemberLevel
eisopFormatting = rootProject.ext.eisopFormatting
}

// Increment the minor version (second number) rather than just the patch
// level (third number) if:
// * any new checkers have been added, or
Expand Down Expand Up @@ -228,7 +240,7 @@ allprojects { currentProj ->
// Always define javacJar, not just when `isJava8` is true, because we redistribute it in checker/build.gradle.
javacJar("com.google.errorprone:javac:9+181-r4173-1")

allProjects subprojects
subprojects.each { sp -> allProjects project(sp.path) }
}

eclipse.classpath {
Expand Down Expand Up @@ -658,8 +670,9 @@ allprojects { currentProj ->
tasks.register('version') {
group = 'Documentation'
description = 'Print Checker Framework version'
def v = version
doLast {
println version
println v
}
}

Expand Down Expand Up @@ -736,7 +749,11 @@ tasks.register('htmlValidate', Exec) {
'/build/',
'/docs/manual/manual.html',
'/docs/manual/plume-bib/docs/index.html',
'/checker/jdk/nullness/src/java/lang/ref/package.html'
'/checker/jdk/nullness/src/java/lang/ref/package.html',
// javadoc generates overview-summary.html as a redirect with
// content="0;index.html" instead of the HTML5-valid "0; URL=index.html".
// This is a javadoc tool bug; suppress it here.
'overview-summary.html'
]
}

Expand Down Expand Up @@ -840,8 +857,8 @@ tasks.register('cleanManual', Exec) {
description = 'Clean the manual'
commandLine 'make', '-C', 'docs/manual', 'clean'
}
clean.dependsOn('cleanManual')
clean {
tasks.named('clean') {
dependsOn 'cleanManual'
delete(file("${rootDir}/docs/api"))
}

Expand Down Expand Up @@ -889,7 +906,6 @@ def createJavadocTask(taskName, taskDescription, memberLevel) {
tasks.register(taskName, Javadoc) {
description = taskDescription
destinationDir = file("${rootDir}/docs/tmpapi")
destinationDir.mkdirs()
subprojects.forEach {
if (!it.name.startsWith('checker-qual-android')) {
source += it.sourceSets.main.allJava
Expand All @@ -900,7 +916,6 @@ def createJavadocTask(taskName, taskDescription, memberLevel) {
// disable interpreting module-info.java files until all sub-modules support them
modularity.inferModulePath = false

destinationDir.deleteDir()
options.memberLevel = memberLevel
options.addBooleanOption('Xdoclint:all', true)
options.addStringOption('Xmaxwarns', '99999')
Expand Down Expand Up @@ -1017,7 +1032,7 @@ subprojects {
}
}

shadowJar {
tasks.named('shadowJar') {
// If you add an external dependency, then do the following:
// * On the master branch and on the modified branch, run:
// ./gradlew assembleForJavac && jar tf checker/dist/checker.jar | grep -v '^annotated-jdk/' | sort > checker-jar-contents.txt
Expand Down Expand Up @@ -1105,25 +1120,25 @@ subprojects {
// Tasks such as `checkResourceLeak` to run various checkers on all the main source sets.
// These pass and are run by the `typecheck` task.
// When you add one here, also update a dependsOn item for the 'typecheck' task.
createCheckTypeTask(project.name, 'Formatter',
rootProject.createCheckTypeTask(project.name,'Formatter',
'org.checkerframework.checker.formatter.FormatterChecker')
createCheckTypeTask(project.name, 'Interning',
rootProject.createCheckTypeTask(project.name,'Interning',
'org.checkerframework.checker.interning.InterningChecker',
[
'-Astubs=javax-lang-model-element-name.astub'
])
createCheckTypeTask(project.name, 'Optional',
rootProject.createCheckTypeTask(project.name,'Optional',
'org.checkerframework.checker.optional.OptionalChecker',
[
// to avoid having to annotate JavaParser
'-AassumePureGetters',
'-AassumeAssertionsAreEnabled',
])
createCheckTypeTask(project.name, 'Purity',
rootProject.createCheckTypeTask(project.name,'Purity',
'org.checkerframework.framework.util.PurityChecker')
createCheckTypeTask(project.name, 'ResourceLeak',
rootProject.createCheckTypeTask(project.name,'ResourceLeak',
'org.checkerframework.checker.resourceleak.ResourceLeakChecker')
createCheckTypeTask(project.name, 'Signature',
rootProject.createCheckTypeTask(project.name,'Signature',
'org.checkerframework.checker.signature.SignatureChecker')

def isDataflow = project.name.is('dataflow')
Expand All @@ -1134,7 +1149,7 @@ subprojects {
// * All files outside the 'framework' and 'checker' subprojects.
// * In the 'framework' and 'checker' subprojects, files with `@AnnotatedFor("nullness")`.
if (isFramework || isChecker) {
createCheckTypeTask(project.name, 'Nullness',
rootProject.createCheckTypeTask(project.name,'Nullness',
'org.checkerframework.checker.nullness.NullnessChecker',
[
'-AskipUses=com\\.sun\\.*',
Expand All @@ -1143,7 +1158,7 @@ subprojects {
'-AconservativeArgumentNullnessAfterInvocation=true',
])
} else {
createCheckTypeTask(project.name, 'Nullness',
rootProject.createCheckTypeTask(project.name,'Nullness',
'org.checkerframework.checker.nullness.NullnessChecker',
[
'-AskipUses=com\\.sun\\.*',
Expand Down Expand Up @@ -1417,9 +1432,10 @@ subprojects {
// The assemble task also produces Javadoc jars, because its purpose is to build
// all artifacts produced by the Gradle project:
// https://docs.gradle.org/current/userguide/base_plugin.html#sec:base_tasks
assemble.dependsOn(':checker:assembleForJavac')

assemble.mustRunAfter(clean)
tasks.named('assemble') {
dependsOn(':checker:assembleForJavac')
mustRunAfter('clean')
}

tasks.register('buildAll') {
group = 'Build'
Expand Down Expand Up @@ -1451,7 +1467,9 @@ tasks.register('releaseAndTest') {
}

// Don't create an empty checker-framework-VERSION.jar
jar.onlyIf {false}
tasks.named('jar') {
onlyIf { false }
}

/**
* Adds the shared pom information to the given publication.
Expand Down
2 changes: 1 addition & 1 deletion checker-qual-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ apply from: rootProject.file('gradle-mvn-push.gradle')

/** Adds information to the publication for uploading to Maven repositories. */
final checkerQualAndroidPom(publication) {
sharedPublicationConfiguration(publication)
rootProject.sharedPublicationConfiguration(publication)
publication.from components.java
publication.pom {
name = 'Checker Qual Android'
Expand Down
8 changes: 4 additions & 4 deletions checker-qual/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ tasks.named('compileModule_infoJava') {
enabled = false
}

compileJava {
tasks.named('compileJava') {
if (!isJava8) {
dependsOn 'compileJava9'
}
}

javadoc {
tasks.named('javadoc') {
modularity.inferModulePath = false
}

jar {
tasks.named('jar') {
manifest {
attributes('Export-Package': '*')
}
Expand All @@ -51,7 +51,7 @@ apply from: rootProject.file('gradle-mvn-push.gradle')

/** Adds information to the publication for uploading to Maven repositories. */
final checkerQualPom(publication) {
sharedPublicationConfiguration(publication)
rootProject.sharedPublicationConfiguration(publication)
publication.from components.java
publication.pom {
name = 'Checker Qual'
Expand Down
2 changes: 1 addition & 1 deletion checker-util/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ apply from: rootProject.file('gradle-mvn-push.gradle')

/** Adds information to the publication for uploading to Maven repositories. */
final checkerUtilPom(publication) {
sharedPublicationConfiguration(publication)
rootProject.sharedPublicationConfiguration(publication)
publication.from components.java
publication.pom {
name = 'Checker Util'
Expand Down
72 changes: 35 additions & 37 deletions checker/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ sourceSets {
}
}

sourcesJar {
dependsOn(generateGitProperties)
tasks.named('sourcesJar') {
dependsOn('generateGitProperties')

// The resources duplicate content from the src directory.
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
Expand Down Expand Up @@ -118,12 +118,14 @@ dependencies {
// produced, depending on what order the tasks are executed. Please refer to
// https://docs.gradle.org/7.1/userguide/validation_problems.html#implicit_dependency for more
// details about this problem.
generateGitProperties.dependsOn(':installGitHooks')
tasks.named('generateGitProperties') {
dependsOn(':installGitHooks')
}
gitProperties {
dotGitDirectory = project.rootProject.layout.projectDirectory.dir(".git")
}

jar {
tasks.named('jar') {
manifest {
attributes('Main-Class': 'org.checkerframework.framework.util.CheckerMain')
}
Expand Down Expand Up @@ -204,7 +206,9 @@ tasks.register('assembleForJavac') {
}
}

assemble.dependsOn 'assembleForJavac'
tasks.named('assemble') {
dependsOn 'assembleForJavac'
}

tasks.register('allSourcesJar', Jar) {
group = 'Build'
Expand Down Expand Up @@ -256,28 +260,20 @@ tasks.register('checkerJar', ShadowJar) {
relocators = shadowJar.getRelocators()
}

jar {
tasks.named('jar') {
dependsOn('checkerJar')
// Never build the skinny jar.
onlyIf {false}
archiveClassifier = 'skinny'
}

shadowJar {
description = 'Creates checker-VERSION-all.jar and copies it to dist/checker.jar.'
tasks.named('shadowJar') {
// assembleForJavac is the task that copies this archive to dist/checker.jar
// (with a declared, cacheable output).
description = 'Creates checker-VERSION-all.jar.'
// To see what files are incorporated into the shadow jar file:
// doFirst { println sourceSets.main.runtimeClasspath.asPath }
archiveClassifier = 'all'
def injectedFiles = project.objects.newInstance(InjectedFileOps)
def shadowArchive = archiveFile
def distDir = file("${projectDir}/dist")
doLast {
injectedFiles.fs.copy {
from shadowArchive
into distDir
rename 'checker.*', 'checker.jar'
}
}

minimize {
// Keep all classes from checker-qual and checker-util rather than
Expand All @@ -302,7 +298,7 @@ artifacts {
fatJar(tasks.named('shadowJar'))
}

clean {
tasks.named('clean') {
def injected = project.objects.newInstance(InjectedExecOps)
def commandLineDir = file('tests/command-line')
def nullnessExtraDir = file('tests/nullness-extra')
Expand Down Expand Up @@ -332,27 +328,29 @@ clean {

// Capture the build directory provider at configuration time.
def cleanBuildDir = layout.buildDirectory
clean.doLast {
def buildDirFile = cleanBuildDir.get().asFile
int maxAttempts = 6
int attempt = 0
while (buildDirFile.exists() && attempt < maxAttempts) {
attempt++
if (attempt > 1) {
sleep(10000) // wait 10 seconds
tasks.named('clean') {
doLast {
def buildDirFile = cleanBuildDir.get().asFile
int maxAttempts = 6
int attempt = 0
while (buildDirFile.exists() && attempt < maxAttempts) {
attempt++
if (attempt > 1) {
sleep(10000) // wait 10 seconds
}
buildDirFile.deleteDir()
}
if (buildDirFile.exists()) {
logger.error("Could not delete ${buildDirFile} after ${maxAttempts} attempt(s). Remaining contents:")
buildDirFile.listFiles()?.each { logger.error(" ${it}") }
throw new GradleException("Failed to delete build directory: ${buildDirFile}")
}
buildDirFile.deleteDir()
}
if (buildDirFile.exists()) {
logger.error("Could not delete ${buildDirFile} after ${maxAttempts} attempt(s). Remaining contents:")
buildDirFile.listFiles()?.each { logger.error(" ${it}") }
throw new GradleException("Failed to delete build directory: ${buildDirFile}")
}
}


// Add non-junit tests
createCheckTypeTask(project.name, 'CompilerMessages',
rootProject.createCheckTypeTask(project.name, 'CompilerMessages',
'org.checkerframework.checker.compilermsgs.CompilerMessagesChecker')
tasks.named('checkCompilerMessages') {
def checkerMsgResources = sourceSets.main.resources.filter { f -> f.name == 'messages.properties' }
Expand Down Expand Up @@ -507,7 +505,7 @@ tasks.register('jtregJdk11Tests', Exec) {
]
}

test {
tasks.named('test') {
if (skipDelombok) {
exclude '**/org/checkerframework/checker/test/junit/CalledMethodsNoDelombokTest.class'
exclude '**/org/checkerframework/checker/test/junit/CalledMethodsDisableReturnsReceiverTest.class'
Expand Down Expand Up @@ -542,7 +540,7 @@ if (!skipDelombok) {
// Tests of the -Ainfer command-line argument. These are not whole-program inference tests.
//

test {
tasks.named('test') {
useJUnit {
// These are run in task ainferTest.
excludeCategories 'org.checkerframework.checker.test.junit.ainferrunners.AinferTestCheckerJaifsGenerationTest'
Expand Down Expand Up @@ -1121,7 +1119,7 @@ apply from: rootProject.file('gradle-mvn-push.gradle')

/** Adds information to the publication for uploading to Maven repositories. */
final checkerPom(publication) {
sharedPublicationConfiguration(publication)
rootProject.sharedPublicationConfiguration(publication)
// Don't use publication.from components.java which would publish the skinny jar as checker.jar.
publication.pom {
name = 'Checker Framework'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@
* check we also propagate the annotations to this constructor in constructorFromUse so that the
* constructor call matches the type given to the NewClassTree.
*
* <p>Note propagation only occurs between two AnnotatedDeclaredTypes. If either side is not an
* AnnotatedDeclaredType then this class does nothing.
*
* @see
* org.checkerframework.checker.nullness.KeyForAnnotatedTypeFactory#constructorFromUse(com.sun.source.tree.NewClassTree)
* <p>Note propagation only occurs between two AnnotatedDeclaredTypes. If either side is not an
* AnnotatedDeclaredType then this class does nothing.
*/
public class KeyForPropagationTreeAnnotator extends TreeAnnotator {
private final KeyForPropagator keyForPropagator;
Expand Down
Loading
Loading