From 83fc7d733314b778f2fd3e1eddfb874fe50dfc6e Mon Sep 17 00:00:00 2001 From: lukaseder Date: Thu, 14 Feb 2019 12:17:44 +0100 Subject: [PATCH] [#5899] jOOQ-checker should provide both checker-framework and ErrorProne checks --- jOOQ-checker/pom.xml | 14 +- .../org/jooq/checker/AbstractChecker.java | 33 +---- .../org/jooq/checker/PlainSQLChecker.java | 45 +----- .../org/jooq/checker/SQLDialectChecker.java | 94 +----------- .../jOOQ-checker-framework-example/README.md | 14 ++ .../jOOQ-checker-framework-example/pom.xml | 138 +++++++++++++----- pom.xml | 26 ++++ 7 files changed, 172 insertions(+), 192 deletions(-) diff --git a/jOOQ-checker/pom.xml b/jOOQ-checker/pom.xml index 65def1ffb4..4c5316b134 100644 --- a/jOOQ-checker/pom.xml +++ b/jOOQ-checker/pom.xml @@ -53,7 +53,19 @@ org.checkerframework checker - 2.5.6 + + + + com.google.errorprone + error_prone_core + + + com.google.errorprone + error_prone_annotation + + + com.google.auto.service + auto-service diff --git a/jOOQ-checker/src/main/java/org/jooq/checker/AbstractChecker.java b/jOOQ-checker/src/main/java/org/jooq/checker/AbstractChecker.java index 2b9e2a1ce5..c8f7c13fa1 100644 --- a/jOOQ-checker/src/main/java/org/jooq/checker/AbstractChecker.java +++ b/jOOQ-checker/src/main/java/org/jooq/checker/AbstractChecker.java @@ -37,23 +37,15 @@ */ package org.jooq.checker; -import static org.checkerframework.javacutil.TreeUtils.elementFromDeclaration; -import static org.checkerframework.javacutil.TreeUtils.enclosingClass; -import static org.checkerframework.javacutil.TreeUtils.enclosingMethod; - import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; -import javax.lang.model.element.Element; +import org.jooq.checker.Tools.Printer; import org.checkerframework.framework.source.Result; import org.checkerframework.framework.source.SourceChecker; -import com.sun.source.tree.ClassTree; -import com.sun.source.tree.MethodTree; -import com.sun.source.util.TreePath; - /** * Common base class for checkers. * @@ -61,15 +53,12 @@ import com.sun.source.util.TreePath; */ abstract class AbstractChecker extends SourceChecker { - void error(Object node, String message) { + Void error(Object node, String message) { getChecker().report(Result.failure(message, node), node); + return null; } - void warn(Object node, String message) { - getChecker().report(Result.warning(message, node), node); - } - - static void print(Printer printer) { + static Void print(Printer printer) { try (PrintWriter writer = new PrintWriter(new FileWriter("error.txt"))){ writer.println("This is probably a bug in jOOQ-checker."); writer.println("If you think this is a bug in jOOQ, please report it here: https://github.com/jOOQ/jOOQ/issues/new"); @@ -78,19 +67,7 @@ abstract class AbstractChecker extends SourceChecker { printer.print(writer); } catch (IOException ignore) {} - } - static Element enclosing(TreePath path) { - MethodTree enclosingMethod = enclosingMethod(path); - - if (enclosingMethod != null) - return elementFromDeclaration(enclosingMethod); - - ClassTree enclosingClass = enclosingClass(path); - return elementFromDeclaration(enclosingClass); - } - - interface Printer { - void print(PrintWriter writer); + return null; } } diff --git a/jOOQ-checker/src/main/java/org/jooq/checker/PlainSQLChecker.java b/jOOQ-checker/src/main/java/org/jooq/checker/PlainSQLChecker.java index 7dd55f500e..695a875721 100644 --- a/jOOQ-checker/src/main/java/org/jooq/checker/PlainSQLChecker.java +++ b/jOOQ-checker/src/main/java/org/jooq/checker/PlainSQLChecker.java @@ -38,14 +38,7 @@ package org.jooq.checker; import static com.sun.source.util.TreePath.getPath; -import static org.checkerframework.javacutil.TreeUtils.elementFromUse; -import java.io.PrintWriter; - -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; - -import org.jooq.Allow; import org.jooq.PlainSQL; import org.checkerframework.framework.source.SourceVisitor; @@ -66,38 +59,12 @@ public class PlainSQLChecker extends AbstractChecker { @Override public Void visitMethodInvocation(MethodInvocationTree node, Void p) { - try { - ExecutableElement elementFromUse = elementFromUse(node); - PlainSQL plainSQL = elementFromUse.getAnnotation(PlainSQL.class); - - // In the absence of a @PlainSQL annotation, - // all jOOQ API method calls will type check. - if (plainSQL != null) { - boolean allowed = false; - Element enclosing = enclosing(getPath(root, node)); - - moveUpEnclosingLoop: - while (enclosing != null) { - if (enclosing.getAnnotation(Allow.PlainSQL.class) != null) { - allowed = true; - break moveUpEnclosingLoop; - } - - enclosing = enclosing.getEnclosingElement(); - } - - if (!allowed) - error(node, "Plain SQL usage not allowed at current scope. Use @Allow.PlainSQL."); - } - } - catch (final Exception e) { - print(new Printer() { - @Override - public void print(PrintWriter t) { - e.printStackTrace(t); - } - }); - } + Tools.checkPlainSQL( + node, + () -> Tools.enclosing(getPath(root, node)), + message -> error(node, message), + printer -> print(printer) + ); return super.visitMethodInvocation(node, p); } diff --git a/jOOQ-checker/src/main/java/org/jooq/checker/SQLDialectChecker.java b/jOOQ-checker/src/main/java/org/jooq/checker/SQLDialectChecker.java index 17234c7ac3..a5f10eafdd 100644 --- a/jOOQ-checker/src/main/java/org/jooq/checker/SQLDialectChecker.java +++ b/jOOQ-checker/src/main/java/org/jooq/checker/SQLDialectChecker.java @@ -38,16 +38,7 @@ package org.jooq.checker; import static com.sun.source.util.TreePath.getPath; -import static java.util.Arrays.asList; -import static org.checkerframework.javacutil.TreeUtils.elementFromUse; -import java.io.PrintWriter; -import java.util.EnumSet; - -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; - -import org.jooq.Allow; import org.jooq.Require; import org.jooq.SQLDialect; import org.jooq.Support; @@ -70,85 +61,12 @@ public class SQLDialectChecker extends AbstractChecker { @Override public Void visitMethodInvocation(MethodInvocationTree node, Void p) { - try { - ExecutableElement elementFromUse = elementFromUse(node); - Support support = elementFromUse.getAnnotation(Support.class); - - // In the absence of a @Support annotation, all jOOQ API method calls will type check. - if (support != null) { - Element enclosing = enclosing(getPath(root, node)); - - // [#7929] "Empty" @Support annotations expand to all SQLDialects - EnumSet supported = EnumSet.copyOf( - support.value().length > 0 - ? asList(support.value()) - : asList(SQLDialect.values()) - ); - - EnumSet allowed = EnumSet.noneOf(SQLDialect.class); - EnumSet required = EnumSet.noneOf(SQLDialect.class); - - boolean evaluateRequire = true; - while (enclosing != null) { - Allow allow = enclosing.getAnnotation(Allow.class); - - if (allow != null) - allowed.addAll(asList(allow.value())); - - if (evaluateRequire) { - Require require = enclosing.getAnnotation(Require.class); - - if (require != null) { - evaluateRequire = false; - - required.clear(); - required.addAll(asList(require.value())); - } - } - - enclosing = enclosing.getEnclosingElement(); - } - - if (allowed.isEmpty()) - error(node, "No jOOQ API usage is allowed at current scope. Use @Allow."); - - boolean allowedFail = true; - allowedLoop: - for (SQLDialect a : allowed) { - for (SQLDialect s : supported) { - if (a.supports(s)) { - allowedFail = false; - break allowedLoop; - } - } - } - - if (allowedFail) - error(node, "The allowed dialects in scope " + allowed + " do not include any of the supported dialects: " + supported); - - boolean requiredFail = false; - requiredLoop: - for (SQLDialect r : required) { - for (SQLDialect s : supported) - if (r.supports(s)) - continue requiredLoop; - - requiredFail = true; - break requiredLoop; - } - - if (requiredFail) - error(node, "Not all of the required dialects " + required + " from the current scope are supported " + supported); - } - } - catch (final Exception e) { - print(new Printer() { - @Override - public void print(PrintWriter t) { - e.printStackTrace(t); - } - }); - } + Tools.checkSQLDialect( + node, + () -> Tools.enclosing(getPath(root, node)), + message -> error(node, message), + printer -> print(printer) + ); return super.visitMethodInvocation(node, p); } diff --git a/jOOQ-examples/jOOQ-checker-framework-example/README.md b/jOOQ-examples/jOOQ-checker-framework-example/README.md index 4cb4b3fe13..5ac24270e0 100644 --- a/jOOQ-examples/jOOQ-checker-framework-example/README.md +++ b/jOOQ-examples/jOOQ-checker-framework-example/README.md @@ -9,4 +9,18 @@ $ pwd $ cd jOOQ-examples/jOOQ-checker-framework-example ... $ mvn clean install +``` + +The above runs a build without any checkers or matchers. + +In order to use the checker framework (supports only Java 8, currently), run + +``` +$ mvn clean install -P checker-framework +``` + +In order to use ErrorProne, run + +``` +$ mvn clean install -P error-prone ``` \ No newline at end of file diff --git a/jOOQ-examples/jOOQ-checker-framework-example/pom.xml b/jOOQ-examples/jOOQ-checker-framework-example/pom.xml index 3a2976f556..da790b6cea 100644 --- a/jOOQ-examples/jOOQ-checker-framework-example/pom.xml +++ b/jOOQ-examples/jOOQ-checker-framework-example/pom.xml @@ -19,6 +19,7 @@ UTF-8 3.12.0-SNAPSHOT + 1.8 @@ -36,42 +37,107 @@ - - - - org.apache.maven.plugins - maven-dependency-plugin - 2.3 - - - - properties - - - - + + + checker-framework - - maven-compiler-plugin - 3.8.0 - - - 10 - + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.3 + + + + properties + + + + - - 10 - 10 - true - - org.jooq.checker.SQLDialectChecker - - - - -Xbootclasspath/p:1.8 - - - - - + + maven-compiler-plugin + 3.8.0 + + + ${java.version} + + + + ${java.version} + ${java.version} + true + + org.jooq.checker.SQLDialectChecker + + + + -Xbootclasspath/p:1.8 + + + + + + + + + + error-prone + + + + + maven-compiler-plugin + 3.8.0 + + javac-with-errorprone + true + + ${java.version} + + + + ${java.version} + ${java.version} + + + org.jooq + jooq-checker + 3.12.0-SNAPSHOT + + + + -Xbootclasspath/p:1.8 + -XDcompilePolicy=simple + -Xplugin:ErrorProne + + + + + org.codehaus.plexus + plexus-compiler-javac-errorprone + 2.8.5 + + + com.google.errorprone + error_prone_core + 2.3.2 + + + org.jooq + jooq + ${org.jooq.version} + + + org.jooq + jooq-checker + ${org.jooq.version} + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6d8df67d85..9007d8351a 100644 --- a/pom.xml +++ b/pom.xml @@ -168,6 +168,32 @@ spring-context 5.0.7.RELEASE + + + + org.checkerframework + checker + 2.5.6 + + + + com.google.errorprone + error_prone_core + 2.3.2 + provided + + + com.google.errorprone + error_prone_annotation + 2.3.2 + provided + + + com.google.auto.service + auto-service + 1.0-rc4 + true +