[#5245] Improved @Require behaviour and spec

This commit is contained in:
lukaseder 2016-05-15 16:15:48 +02:00
parent 4ff2c39776
commit a603d745fb
6 changed files with 112 additions and 29 deletions

View File

@ -58,6 +58,10 @@ abstract class AbstractChecker extends SourceChecker {
getChecker().report(Result.failure(message, node), node);
}
void warn(Object node, String message) {
getChecker().report(Result.warning(message, node), node);
}
void print(Printer printer) {
try (PrintWriter writer = new PrintWriter(new FileWriter("error.txt"))){
writer.println("This is probably a bug in jOOQ-checker.");

View File

@ -86,18 +86,25 @@ public class SQLDialectChecker extends AbstractChecker {
EnumSet<SQLDialect> supported = EnumSet.copyOf(asList(support.value()));
EnumSet<SQLDialect> allowed = EnumSet.noneOf(SQLDialect.class);
EnumSet<SQLDialect> required = EnumSet.allOf(SQLDialect.class);
EnumSet<SQLDialect> x;
EnumSet<SQLDialect> required = EnumSet.noneOf(SQLDialect.class);
boolean evaluateRequire = true;
while (enclosing != null) {
Allow allow = enclosing.getAnnotation(Allow.class);
Require require = enclosing.getAnnotation(Require.class);
if (allow != null)
allowed.addAll(asList(allow.value()));
if (require != null)
required.retainAll(asList(require.value()));
if (evaluateRequire) {
Require require = enclosing.getAnnotation(Require.class);
if (require != null) {
evaluateRequire = false;
required.clear();
required.addAll(asList(require.value()));
}
}
enclosing = enclosing.getEnclosingElement();
}
@ -108,13 +115,33 @@ public class SQLDialectChecker extends AbstractChecker {
if (required.isEmpty())
error(node, "No jOOQ API usage is allowed at current scope due to conflicting @Require specification.");
x = EnumSet.copyOf(allowed);
x.retainAll(supported);
if (x.isEmpty())
error(node, "None of the supported dialects (" + supported + ") are allowed in the current scope (" + allowed + ")");
boolean allowedFail = true;
allowedLoop:
for (SQLDialect a : allowed) {
for (SQLDialect s : supported) {
if (a.supports(s)) {
allowedFail = false;
break allowedLoop;
}
}
}
if (!supported.containsAll(required))
error(node, "Not all of the required dialects (" + required + ") from the current scope are supported (" + supported + ")");
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) {

View File

@ -60,7 +60,7 @@
<fork>true</fork>
<annotationProcessors>
<annotationProcessor>org.jooq.checker.SQLDialectChecker</annotationProcessor>
<annotationProcessor>org.jooq.checker.PlainSQLChecker</annotationProcessor>
<!-- <annotationProcessor>org.jooq.checker.PlainSQLChecker</annotationProcessor> -->
</annotationProcessors>
<compilerArgs>
<arg>-Xbootclasspath/p:1.8</arg>

View File

@ -1,35 +1,87 @@
package org.jooq.example.checker;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.MYSQL;
// ...
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.POSTGRES_9_4;
import static org.jooq.SQLDialect.POSTGRES_9_5;
import org.jooq.Allow;
import org.jooq.Require;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
// The class requires both H2 and MySQL
// The inherited @Allow annotation from the package allows only MySQL, though.
@Require({ SQLDialect.H2, SQLDialect.MYSQL })
// The class requires the H2, MYSQL, and POSTGRES_9_5 families
// The inherited @Allow annotation from the package allows only the MYSQL family, though.
@Require({ H2, MYSQL, POSTGRES_9_5 })
public class SQLDialectCheckerTests {
// @Allow = MySQL (inherited from package)
// @Require = { H2, MySQL } (inherited from class)
public static void doesntCompileBecauseH2IsNotAllowedAndMySQLIsNotSupported() {
// @Allow = MYSQL (inherited from package)
// @Require = { H2, MYSQL, POSTGRES_9_5 }
public static void doesntCompileBecauseOnlyMySQLIsAllowed() {
DSL.array(2);
}
// @Allow = { H2, MySQL (inherited from package) }
// @Require = { H2, MySQL } (inherited from class)
// @Allow = { MYSQL (inherited from package), POSTGRES_9_4 }
// @Require = { POSTGRES_9_4 }
@Allow(POSTGRES_9_4)
@Require(POSTGRES_9_4)
public static void doesntCompileBecausePostgres95IsNotAllowed() {
DSL.cube(DSL.inline(1));
}
// @Allow = { MYSQL (inherited from package), POSTGRES_9_5 }
// @Require = { POSTGRES_9_5 }
@Allow(POSTGRES_9_5)
@Require(POSTGRES_9_5)
public static void compilesBecausePostgres95IsAllowed() {
DSL.cube(DSL.inline(1));
}
// @Allow = { MYSQL (inherited from package), POSTGRES }
// @Require = { POSTGRES }
@Allow(POSTGRES)
@Require(POSTGRES)
public static void compilesBecausePostgresIsAllowedAndRequired() {
DSL.cube(DSL.inline(1));
}
// @Allow = { MYSQL (inherited from package), POSTGRES }
// @Require = { POSTGRES_9_4 }
@Allow(POSTGRES)
@Require(POSTGRES_9_4)
public static void doesntCompileBecausePostgres94IsRequired() {
DSL.cube(DSL.inline(1));
}
// @Allow = { MYSQL (inherited from package), POSTGRES_9_4 }
// @Require = { POSTGRES }
@Allow(POSTGRES_9_4)
@Require(POSTGRES)
public static void compilesBecausePostgres94IsAllowed() {
DSL.lateral(DSL.dual());
}
// @Allow = { H2, MYSQL (inherited from package) }
// @Require = { H2, MYSQL, POSTGRES_9_5 } (inherited from class)
@Allow(H2)
public static void doesntCompileBecauseMySQLIsNotSupported() {
public static void doesntCompileBecauseMYSQLIsNotSupported() {
DSL.array(2);
}
// @Allow = { H2, MySQL (inherited from package) }
// @Require = { H2, MySQL } (inherited from class)
// @Allow = { H2, MYSQL (inherited from package) }
// @Require = { H2 }
@Allow(H2)
@Require(H2)
public static void compiles() {
public static void compilesBecauseH2IsAllowedAndRequired() {
DSL.array(2);
}
// @Allow = { H2, MYSQL (inherited from package) }
// @Require = { H2 }
@Allow(H2)
@Require({ H2, ORACLE })
public static void doesntCompileAsOracleCannotBeRequiredInScope() {
DSL.array(2);
}
}

View File

@ -122,8 +122,8 @@ import java.lang.annotation.Target;
* <ul>
* <li>In the absence of any {@link Allow} annotation, no jOOQ API usage is
* allowed.</li>
* <li>The combination of all {@link Allow} and {@link Require} annotations is
* applied for any given scope.</li>
* <li>The combination of all {@link Allow} annotations and of the inner-most
* {@link Require} annotation is applied for any given scope.</li>
* <li>Nested packages are not creating nested scopes.</li>
* <li>If a versioned {@link SQLDialect} is allowed (rather than a
* {@link SQLDialect#family()}), then the allowed version, all of its

View File

@ -103,8 +103,8 @@ import java.lang.annotation.Target;
* <ul>
* <li>In the absence of any {@link Allow} annotation, no jOOQ API usage is
* allowed.</li>
* <li>The combination of all {@link Allow} and {@link Require} annotations is
* applied for any given scope.</li>
* <li>The combination of all {@link Allow} annotations and of the inner-most
* {@link Require} annotation is applied for any given scope.</li>
* <li>Nested packages are not creating nested scopes.</li>
* <li>If a versioned {@link SQLDialect} is required (rather than a
* {@link SQLDialect#family()}), then the required version, any of its