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 spotlesscheck to build.gradle and CI #430

Closed
wants to merge 4 commits into from
Closed
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
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ jobs:
run: |
python3 -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Spotless Check
if: matrix.jdk == 11 || matrix.jdk == 17
run: ./gradlew spotlessCheck
- name: Build
run: |
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
Expand Down
181 changes: 144 additions & 37 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
buildscript {
dependencies {
if (JavaVersion.current() >= JavaVersion.VERSION_11) {
// Code formatting; defines targets "spotlessApply" and "spotlessCheck".
// https://github.com/diffplug/spotless/tags ; see tags starting "gradle/"
// Only works on JDK 11+.
classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.22.0'
}
}
}

plugins {
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
Expand All @@ -19,22 +30,104 @@ ext {
// On a Java 8 JVM, use error-prone javac and source/target 8.
// On a Java 9+ JVM, use the host javac, default source/target, and required module flags.
isJava8 = JavaVersion.current() == JavaVersion.VERSION_1_8
isJava14 = JavaVersion.current() == JavaVersion.VERSION_14
isJava15 = JavaVersion.current() == JavaVersion.VERSION_15
isJava16 = JavaVersion.current() == JavaVersion.VERSION_16
isJava17 = JavaVersion.current() == JavaVersion.VERSION_17
isJava18 = JavaVersion.current() == JavaVersion.VERSION_18
isJava19 = JavaVersion.current() == JavaVersion.VERSION_19
isJava20 = JavaVersion.current() == JavaVersion.VERSION_20
isJava21 = JavaVersion.current() == JavaVersion.VERSION_21

isJava21plus = isJava21
isJava20plus = isJava20 || isJava21plus
isJava19plus = isJava19 || isJava20plus
isJava18plus = isJava18 || isJava19plus
isJava17plus = isJava17 || isJava18plus
isJava16plus = isJava16 || isJava17plus
isJava15plus = isJava15 || isJava16plus
isJava14plus = isJava14 || isJava15plus
isJava11plus = JavaVersion.current() >= JavaVersion.VERSION_11

errorproneJavacVersion = '9+181-r4173-1'

// Keep in sync with checker-framework/build.gradle.
// TODO: find a way to directly use that variable.
compilerArgsForRunningCF = [
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
"--add-opens", "jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
"--add-exports",
"jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
"--add-opens",
"jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
]

if (isJava11plus) {
apply plugin: 'com.diffplug.spotless'
spotless {
format 'misc', {
target '*.md', '*.tex', '.gitignore', 'Makefile'
indentWithSpaces(2)
trimTrailingWhitespace()
}

java {
googleJavaFormat().aosp()
importOrder('com', 'jdk', 'lib', 'lombok', 'org', 'java', 'javax')
formatAnnotations().addTypeAnnotation("PolyInitialized")
}

groovyGradle {
target '**/*.gradle'
greclipse() // which formatter Spotless should use to format .gradle files.
indentWithSpaces(4)
trimTrailingWhitespace()
}
}
}
}

if (isJava11plus) {
apply plugin: 'com.diffplug.spotless'
spotless {
// Resolve the Spotless plugin dependencies from the buildscript repositories rather than the
// project repositories. That way the spotless plugin does not use the locally built version of
// checker-qual as a dependency. Without this, errors like the follow are issued when running
// a spotless task without a locally-built version of checker-qual.jar:
// Could not determine the dependencies of task ':checker-qual:spotlessCheck'.
// > Could not create task ':checker-qual:spotlessJavaCheck'.
// > Could not create task ':checker-qual:spotlessJava'.
// > File signature can only be created for existing regular files, given:
// .../checker-framework/checker-qual/build/libs/checker-qual-3.25.1-SNAPSHOT.jar
predeclareDepsFromBuildscript()
}

spotlessPredeclare {
// Put all the formatters that have dependencies here. Without this, errors like the following
// will happen:
// Could not determine the dependencies of task ':spotlessCheck'.
// > Could not create task ':spotlessJavaCheck'.
// > Could not create task ':spotlessJava'.
// > Add a step with [com.google.googlejavaformat:google-java-format:1.15.0] into the `spotlessPredeclare` block in the root project.
java {
googleJavaFormat()
}
groovyGradle {
greclipse()
}
}
}

println '===================================='
Expand Down Expand Up @@ -127,7 +220,7 @@ test {
dependsOn('dist')

systemProperties 'path.afu.scripts': "${afu}/scripts",
'use.hacks': true
'use.hacks': true

systemProperties += [JDK_JAR: "${checkerFrameworkPath}/checker/dist/jdk8.jar"]

Expand All @@ -136,7 +229,9 @@ test {
}

if (isJava8) {
jvmArgs += ["-Xbootclasspath/p:${configurations.javacJar.asPath}"]
jvmArgs += [
"-Xbootclasspath/p:${configurations.javacJar.asPath}"
]
} else {
// Without this, the test throw "java.lang.OutOfMemoryError: Java heap space"
// Corresponding pull request: https://github.com/opprop/checker-framework-inference/pull/263
Expand Down Expand Up @@ -166,21 +261,21 @@ test {
"Skipped: ${result.skippedTestCount}, " +
"Time elapsed: ${seconds} sec\n"
}

}
}

compileJava {
dependsOn(buildLingeling)
dependsOn(buildDLJC)
options.compilerArgs = [
'-implicit:class',
'-Awarns',
'-Xmaxwarns', '10000',
// Can't use this because JSON library contains raw types:
// '-Xlint:unchecked',
'-Xlint:deprecation',
'-Werror',
'-implicit:class',
'-Awarns',
'-Xmaxwarns',
'10000',
// Can't use this because JSON library contains raw types:
// '-Xlint:unchecked',
'-Xlint:deprecation',
'-Werror',
]
}

Expand Down Expand Up @@ -214,7 +309,7 @@ task dist(dependsOn: shadowJar, type: Copy) {
"${checkerFrameworkPath}/checker/dist/checker-qual.jar",
"${checkerFrameworkPath}/checker/dist/checker-util.jar",
"${checkerFrameworkPath}/checker/dist/javac.jar",
)
)
into file('dist')
}

Expand Down Expand Up @@ -270,20 +365,30 @@ task cloneAndBuildDependencies(type: Exec) {
task testCheckerInferenceScript(type: Exec, dependsOn: dist) {
description 'Basic sanity check of scripts/inference'
executable './scripts/inference'
args = ['--mode', 'TYPECHECK',
'--checker', 'ostrusted.OsTrustedChecker',
'--solver', 'checkers.inference.solver.PropagationSolver',
'testdata/ostrusted/Test.java']
args = [
'--mode',
'TYPECHECK',
'--checker',
'ostrusted.OsTrustedChecker',
'--solver',
'checkers.inference.solver.PropagationSolver',
'testdata/ostrusted/Test.java'
]
}

task testCheckerInferenceDevScript(type: Exec, dependsOn: [dist, dependenciesJar]) {
description 'Basic sanity check of scripts/inference-dev'
executable './scripts/inference-dev'
args = ['--mode', 'INFER',
'--checker', 'interning.InterningChecker',
'--solver', 'checkers.inference.solver.MaxSat2TypeSolver',
'--hacks=true',
'testdata/interning/MapAssignment.java']
args = [
'--mode',
'INFER',
'--checker',
'interning.InterningChecker',
'--solver',
'checkers.inference.solver.MaxSat2TypeSolver',
'--hacks=true',
'testdata/interning/MapAssignment.java'
]
}

task testDataflowExternalSolvers(type: Exec, dependsOn: [dist, dependenciesJar]) {
Expand All @@ -294,10 +399,10 @@ task testDataflowExternalSolvers(type: Exec, dependsOn: [dist, dependenciesJar])
afterEvaluate {
// Create a task for each test class whose name is the same as the class name.
sourceSets.test.java.filter {
it.path.contains('tests/checkers') &&
it.path.endsWith('Test.java') &&
!it.path.contains('CFInferenceTest')
}.forEach { file ->
it.path.contains('tests/checkers') &&
it.path.endsWith('Test.java') &&
!it.path.contains('CFInferenceTest')
}.forEach { file ->
String junitClassName = file.name.replaceAll(".java", "")
tasks.create(name: "${junitClassName}", type: Test, group: 'Verification') {
description "Run ${junitClassName} tests."
Expand All @@ -310,16 +415,18 @@ afterEvaluate {
dependsOn(shadowJar)

systemProperties 'path.afu.scripts': "${afu}/scripts",
'path.inference.script': "${projectDir}/scripts/inference",
'use.hacks': true,
JDK_JAR: "${checkerFrameworkPath}/checker/dist/jdk8.jar"
'path.inference.script': "${projectDir}/scripts/inference",
'use.hacks': true,
JDK_JAR: "${checkerFrameworkPath}/checker/dist/jdk8.jar"

if (project.hasProperty('emit.test.debug')) {
systemProperties += ["emit.test.debug": 'true']
}

if (isJava8) {
jvmArgs += ["-Xbootclasspath/p:${configurations.javacJar.asPath}"]
jvmArgs += [
"-Xbootclasspath/p:${configurations.javacJar.asPath}"
]
}

testLogging {
Expand Down
50 changes: 27 additions & 23 deletions src/checkers/inference/BaseInferrableChecker.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
package checkers.inference;

import com.sun.source.tree.Tree;
import com.sun.source.util.Trees;

import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory;
import org.checkerframework.framework.flow.CFAnalysis;
import org.checkerframework.framework.flow.CFStore;
import org.checkerframework.framework.flow.CFTransfer;
import org.checkerframework.framework.flow.CFValue;
import org.checkerframework.framework.type.GenericAnnotatedTypeFactory;
import org.checkerframework.javacutil.Pair;

import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.VariableElement;

import checkers.inference.dataflow.InferenceAnalysis;
import checkers.inference.dataflow.InferenceTransfer;
import checkers.inference.model.ConstraintManager;

import com.sun.source.tree.Tree;
import com.sun.source.util.Trees;

/**
* Default implementation of InferrableChecker.
*
*/
/** Default implementation of InferrableChecker. */
public abstract class BaseInferrableChecker extends InferenceChecker implements InferrableChecker {

@Override
Expand All @@ -32,7 +27,7 @@ public void initChecker() {
// except for the last line assigning the visitor
{
Trees trees = Trees.instance(processingEnv);
assert( trees != null ); /*nninvariant*/
assert (trees != null); /*nninvariant*/
this.trees = trees;

this.messager = processingEnv.getMessager();
Expand All @@ -43,7 +38,8 @@ public void initChecker() {
}

@Override
public InferenceVisitor<?, ?> createVisitor(InferenceChecker ichecker, BaseAnnotatedTypeFactory factory, boolean infer) {
public InferenceVisitor<?, ?> createVisitor(
InferenceChecker ichecker, BaseAnnotatedTypeFactory factory, boolean infer) {
return new InferenceVisitor<>(this, ichecker, factory, infer);
}

Expand All @@ -54,11 +50,11 @@ public BaseInferenceRealTypeFactory createRealTypeFactory(boolean infer) {

@Override
public CFAnalysis createInferenceAnalysis(
InferenceChecker checker,
GenericAnnotatedTypeFactory<CFValue, CFStore, CFTransfer, CFAnalysis> factory,
SlotManager slotManager,
ConstraintManager constraintManager,
InferrableChecker realChecker) {
InferenceChecker checker,
GenericAnnotatedTypeFactory<CFValue, CFStore, CFTransfer, CFAnalysis> factory,
SlotManager slotManager,
ConstraintManager constraintManager,
InferrableChecker realChecker) {

return new InferenceAnalysis(checker, factory, slotManager, constraintManager, realChecker);
}
Expand All @@ -84,12 +80,20 @@ public boolean shouldStoreConstantSlots() {
}

@Override
public InferenceAnnotatedTypeFactory createInferenceATF(InferenceChecker inferenceChecker,
InferrableChecker realChecker, BaseAnnotatedTypeFactory realTypeFactory,
SlotManager slotManager, ConstraintManager constraintManager) {
InferenceAnnotatedTypeFactory InferenceAFT = new InferenceAnnotatedTypeFactory(
inferenceChecker, realChecker.withCombineConstraints(), realTypeFactory, realChecker,
slotManager, constraintManager);
public InferenceAnnotatedTypeFactory createInferenceATF(
InferenceChecker inferenceChecker,
InferrableChecker realChecker,
BaseAnnotatedTypeFactory realTypeFactory,
SlotManager slotManager,
ConstraintManager constraintManager) {
InferenceAnnotatedTypeFactory InferenceAFT =
new InferenceAnnotatedTypeFactory(
inferenceChecker,
realChecker.withCombineConstraints(),
realTypeFactory,
realChecker,
slotManager,
constraintManager);
return InferenceAFT;
}

Expand Down
Loading