aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoel Spilker <r.spilker@gmail.com>2017-02-28 01:01:35 +0100
committerRoel Spilker <r.spilker@gmail.com>2017-03-22 21:53:55 +0100
commit0407894b65eaaf6a83eb5e5ee45249fa0db8b409 (patch)
treed2757fa319a43cab58fc40aaf49d5f12d3ae8859
parentbf54986e8a08d246877fae902c58dc41ca2f559b (diff)
downloadlombok-0407894b65eaaf6a83eb5e5ee45249fa0db8b409.tar.gz
lombok-0407894b65eaaf6a83eb5e5ee45249fa0db8b409.tar.bz2
lombok-0407894b65eaaf6a83eb5e5ee45249fa0db8b409.zip
[jdk9] Fix bug regarding multipleError field
-rw-r--r--src/core/lombok/javac/JavacAST.java145
1 files changed, 123 insertions, 22 deletions
diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java
index c99ae5c9..91ed325f 100644
--- a/src/core/lombok/javac/JavacAST.java
+++ b/src/core/lombok/javac/JavacAST.java
@@ -65,12 +65,12 @@ import com.sun.tools.javac.util.Name;
* something javac's own AST system does not offer.
*/
public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
- private final Messager messager;
private final JavacElements elements;
private final JavacTreeMaker treeMaker;
private final Symtab symtab;
private final JavacTypes javacTypes;
private final Log log;
+ private final ErrorLog errorLogger;
private final Context context;
/**
@@ -84,8 +84,8 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
super(sourceName(top), PackageName.getPackageName(top), new JavacImportList(top), statementTypes());
setTop(buildCompilationUnit(top));
this.context = context;
- this.messager = messager;
this.log = Log.instance(context);
+ this.errorLogger = ErrorLog.create(messager, log);
this.elements = JavacElements.instance(context);
this.treeMaker = new JavacTreeMaker(TreeMaker.instance(context));
this.symtab = Symtab.instance(context);
@@ -422,22 +422,21 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
try {
switch (kind) {
case ERROR:
- increaseErrorCount(messager);
- boolean prev = log.multipleErrors;
- log.multipleErrors = true;
- try {
- log.error(pos, "proc.messager", message);
- } finally {
- log.multipleErrors = prev;
- }
+ errorLogger.error(pos, message);
+ break;
+ case MANDATORY_WARNING:
+ errorLogger.mandatoryWarning(pos, message);
break;
- default:
case WARNING:
- log.warning(pos, "proc.messager", message);
+ errorLogger.warning(pos, message);
+ break;
+ default:
+ case NOTE:
+ errorLogger.note(pos, message);
break;
}
} finally {
- if (oldSource != null) log.useSource(oldSource);
+ if (newSource != null) log.useSource(oldSource);
}
}
@@ -475,16 +474,118 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
return oldL;
}
- private void increaseErrorCount(Messager m) {
- try {
- Field f = m.getClass().getDeclaredField("errorCount");
- f.setAccessible(true);
- if (f.getType() == int.class) {
- int val = ((Number)f.get(m)).intValue();
- f.set(m, val +1);
+ abstract static class ErrorLog {
+ final Log log;
+ private final Messager messager;
+ private final Field errorCount;
+ private final Field warningCount;
+
+ private ErrorLog(Log log, Messager messager, Field errorCount, Field warningCount) {
+ this.log = log;
+ this.messager = messager;
+ this.errorCount = errorCount;
+ this.warningCount = warningCount;
+ }
+
+ final void error(DiagnosticPosition pos, String message) {
+ increment(errorCount);
+ error1(pos, message);
+ }
+
+ final void warning(DiagnosticPosition pos, String message) {
+ increment(warningCount);
+ log.warning(pos, "proc.messager", message);
+ }
+
+ final void mandatoryWarning(DiagnosticPosition pos, String message) {
+ increment(warningCount);
+ log.mandatoryWarning(pos, "proc.messager", message);
+ }
+
+ final void note(DiagnosticPosition pos, String message) {
+ log.note(pos, "proc.messager", message);
+ }
+
+ abstract void error1(DiagnosticPosition pos, String message);
+
+ private void increment(Field field) {
+ if (field == null) return;
+ try {
+ int val = ((Number)field.get(messager)).intValue();
+ field.set(messager, val +1);
+ } catch (Throwable t) {
+ //Very unfortunate, but in most cases it still works fine, so we'll silently swallow it.
}
- } catch (Throwable t) {
- //Very unfortunate, but in most cases it still works fine, so we'll silently swallow it.
+ }
+
+ static ErrorLog create(Messager messager, Log log) {
+ Field errorCount = null;
+ try {
+ Field f = messager.getClass().getDeclaredField("errorCount");
+ f.setAccessible(true);
+ errorCount = f;
+ } catch (Throwable t) {}
+ boolean hasMultipleErrors = false;
+ for (Field field : log.getClass().getFields()) {
+ if (field.getName().equals("multipleErrors")) {
+ hasMultipleErrors = true;
+ break;
+ }
+ }
+ if (hasMultipleErrors) return new JdkBefore9(log, messager, errorCount);
+
+ Field warningCount = null;
+ try {
+ Field f = messager.getClass().getDeclaredField("warningCount");
+ f.setAccessible(true);
+ warningCount = f;
+ } catch (Throwable t) {}
+
+
+ Method logMethod = null;
+ Object multiple = null;
+ try {
+ Class<?> df = Class.forName("com.sun.tools.javac.util.JCDiagnostic$DiagnosticFlag");
+ for (Object constant : df.getEnumConstants()) {
+ if (constant.toString().equals("MULTIPLE")) multiple = constant;
+ }
+ logMethod = log.getClass().getMethod("error", new Class<?>[] {df, DiagnosticPosition.class, String.class, Object[].class});
+ } catch (Throwable t) {}
+
+ return new Jdk9Plus(log, messager, errorCount, warningCount, logMethod, multiple);
+ }
+ }
+
+ static class JdkBefore9 extends ErrorLog {
+ private JdkBefore9(Log log, Messager messager, Field errorCount) {
+ super(log, messager, errorCount, null);
+ }
+
+ @Override void error1(DiagnosticPosition pos, String message) {
+ boolean prev = log.multipleErrors;
+ log.multipleErrors = true;
+ try {
+ log.error(pos, "proc.messager", message);
+ } finally {
+ log.multipleErrors = prev;
+ }
+ }
+ }
+
+ static class Jdk9Plus extends ErrorLog {
+ private final Object multiple;
+ private final Method logMethod;
+
+ private Jdk9Plus(Log log, Messager messager, Field errorCount, Field warningCount, Method logMethod, Object multiple) {
+ super(log, messager, errorCount, warningCount);
+ this.logMethod = logMethod;
+ this.multiple = multiple;
+ }
+
+ @Override void error1(DiagnosticPosition pos, String message) {
+ try {
+ logMethod.invoke(multiple, pos, "proc.messager", message);
+ } catch (Throwable t) {}
}
}
}