aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoel Spilker <r.spilker@gmail.com>2014-01-17 21:13:37 +0100
committerRoel Spilker <r.spilker@gmail.com>2014-01-17 21:13:37 +0100
commitfee535eae94557287c1762edd32374ddfc311367 (patch)
tree1463734034734721ff2f6c2a41cf1100f16603bb
parent610f250c1d84d98537ecd480ce19c4894bce503b (diff)
downloadlombok-fee535eae94557287c1762edd32374ddfc311367.tar.gz
lombok-fee535eae94557287c1762edd32374ddfc311367.tar.bz2
lombok-fee535eae94557287c1762edd32374ddfc311367.zip
[configuration] Added @PrintConfiguration to print the combined interpreted configuration for a certain java file, improved problem reporting
-rw-r--r--src/core/lombok/core/LombokConfiguration.java51
-rw-r--r--src/core/lombok/core/PrintConfiguration.java40
-rw-r--r--src/core/lombok/core/configuration/ConfigurationErrorReporter.java8
-rw-r--r--src/core/lombok/core/configuration/ConfigurationErrorReporterFactory.java4
-rw-r--r--src/core/lombok/core/configuration/ConfigurationKey.java39
-rw-r--r--src/core/lombok/core/configuration/FileSystemSourceCache.java2
-rw-r--r--src/core/lombok/core/configuration/StringConfigurationSource.java25
-rw-r--r--src/core/lombok/eclipse/handlers/HandlePrintConfiguration.java63
-rw-r--r--src/core/lombok/javac/handlers/HandlePrintConfiguration.java65
9 files changed, 270 insertions, 27 deletions
diff --git a/src/core/lombok/core/LombokConfiguration.java b/src/core/lombok/core/LombokConfiguration.java
index 0c391bf4..e64ddbbc 100644
--- a/src/core/lombok/core/LombokConfiguration.java
+++ b/src/core/lombok/core/LombokConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Project Lombok Authors.
+ * Copyright (C) 2013-2014 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,12 @@
*/
package lombok.core;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+
import lombok.core.configuration.BubblingConfigurationResolver;
+import lombok.core.configuration.ConfigurationErrorReporter;
import lombok.core.configuration.ConfigurationErrorReporterFactory;
import lombok.core.configuration.ConfigurationKey;
import lombok.core.configuration.FileSystemSourceCache;
@@ -35,6 +40,48 @@ public class LombokConfiguration {
}
static <T> T read(ConfigurationKey<T> key, AST<?, ?, ?> ast) {
- return new BubblingConfigurationResolver(cache.sourcesForJavaFile(ast.getAbsoluteFileLocation(), ConfigurationErrorReporterFactory.CONSOLE)).resolve(key);
+ return createResolver(ast, ConfigurationErrorReporterFactory.CONSOLE, cache).resolve(key);
+ }
+
+ public static void writeConfiguration(AST<?, ?, ?> ast, PrintStream stream) {
+ final List<String> problems = new ArrayList<String>();
+ ConfigurationErrorReporterFactory reporterFactory = new ConfigurationErrorReporterFactory() {
+ @Override public ConfigurationErrorReporter createFor(final String description) {
+ return new ConfigurationErrorReporter() {
+ @Override
+ public void report(String error, int lineNumber, String line) {
+ problems.add(String.format("%s (%s:%d)", error, description, lineNumber));
+ }
+ };
+ }
+ };
+
+ stream.printf("Combined lombok configuration for '%s'\n\n", ast.getAbsoluteFileLocation());
+ // create a new empty 'cache' to make sure all problems are reported
+ FileSystemSourceCache sourceCache = new FileSystemSourceCache();
+ BubblingConfigurationResolver resolver = createResolver(ast, reporterFactory, sourceCache);
+ for (ConfigurationKey<?> key : ConfigurationKey.registeredKeys()) {
+ Object value = resolver.resolve(key);
+ if (value == null || value instanceof List<?> && ((List<?>)value).isEmpty()) continue;
+ stream.printf("%s: %s\n", key.getKeyName(), value);
+ }
+
+ if (!problems.isEmpty()) {
+ stream.println();
+ stream.printf("Problems encountered during parsing: %d\n", problems.size());
+ int i = 1;
+ for (String problem : problems) {
+ stream.printf("%4d - %s\n", i, problem);
+ i++;
+ }
+ }
+ }
+
+ private static BubblingConfigurationResolver createResolver(AST<?, ?, ?> ast, ConfigurationErrorReporterFactory reporterFactory, FileSystemSourceCache sourceCache) {
+ return new BubblingConfigurationResolver(sourceCache.sourcesForJavaFile(ast.getAbsoluteFileLocation(), reporterFactory));
+ }
+
+ public static void main(String[] args) {
+ System.out.println(" \n \n ".trim().length());
}
}
diff --git a/src/core/lombok/core/PrintConfiguration.java b/src/core/lombok/core/PrintConfiguration.java
new file mode 100644
index 00000000..05d4ab4d
--- /dev/null
+++ b/src/core/lombok/core/PrintConfiguration.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.core;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Will print the combined interpreted configuration from 'lombok.config' files.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+public @interface PrintConfiguration {
+ /**
+ * Normally, the configuration is printed to standard out, but you can pick a filename instead. Useful for many IDEs
+ * which don't have a console unless you start them from the command line.
+ */
+ String outfile() default "";
+}
diff --git a/src/core/lombok/core/configuration/ConfigurationErrorReporter.java b/src/core/lombok/core/configuration/ConfigurationErrorReporter.java
index 26fa9cc2..901d313b 100644
--- a/src/core/lombok/core/configuration/ConfigurationErrorReporter.java
+++ b/src/core/lombok/core/configuration/ConfigurationErrorReporter.java
@@ -22,11 +22,5 @@
package lombok.core.configuration;
public interface ConfigurationErrorReporter {
- ConfigurationErrorReporter CONSOLE = new ConfigurationErrorReporter() {
- @Override public void report(String error) {
- System.err.println(error);
- }
- };
-
- void report(String error);
+ void report(String error, int lineNumber, String line);
} \ No newline at end of file
diff --git a/src/core/lombok/core/configuration/ConfigurationErrorReporterFactory.java b/src/core/lombok/core/configuration/ConfigurationErrorReporterFactory.java
index b5bd9056..2ae1cb08 100644
--- a/src/core/lombok/core/configuration/ConfigurationErrorReporterFactory.java
+++ b/src/core/lombok/core/configuration/ConfigurationErrorReporterFactory.java
@@ -27,8 +27,8 @@ public interface ConfigurationErrorReporterFactory {
public ConfigurationErrorReporter createFor(final String description) {
return new ConfigurationErrorReporter() {
@Override
- public void report(String error) {
- System.err.printf("Error in %s: %s\n", description, error);
+ public void report(String error, int lineNumber, String line) {
+ System.err.printf("%s (%s:%d)", error, description, lineNumber);
}
};
}
diff --git a/src/core/lombok/core/configuration/ConfigurationKey.java b/src/core/lombok/core/configuration/ConfigurationKey.java
index 81a5dfaa..f6711cca 100644
--- a/src/core/lombok/core/configuration/ConfigurationKey.java
+++ b/src/core/lombok/core/configuration/ConfigurationKey.java
@@ -22,7 +22,9 @@
package lombok.core.configuration;
import java.util.Collections;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.TreeMap;
/**
@@ -48,7 +50,12 @@ public abstract class ConfigurationKey<T> {
registerKey(keyName, type);
}
-
+
+ private ConfigurationKey(String keyName, ConfigurationDataType type) {
+ this.keyName = keyName;
+ this.type = type;
+ }
+
public final String getKeyName() {
return keyName;
}
@@ -87,13 +94,41 @@ public abstract class ConfigurationKey<T> {
* Returns a copy of the currently registered keys.
*/
@SuppressWarnings("unchecked")
- public static Map<String, ConfigurationDataType> registeredKeys() {
+ public static Map<String, ConfigurationDataType> registeredKeysAsMap() {
synchronized (registeredKeys) {
if (copy == null) copy = Collections.unmodifiableMap((Map<String, ConfigurationDataType>) registeredKeys.clone());
return copy;
}
}
+ public static Iterable<ConfigurationKey<?>> registeredKeys() {
+ class LocalConfigurationKey extends ConfigurationKey<Object> {
+ public LocalConfigurationKey(Entry<String, ConfigurationDataType> entry) {
+ super(entry.getKey(), entry.getValue());
+ }
+ }
+ final Map<String, ConfigurationDataType> map = registeredKeysAsMap();
+ return new Iterable<ConfigurationKey<?>>() {
+ @Override public Iterator<ConfigurationKey<?>> iterator() {
+ final Iterator<Entry<String, ConfigurationDataType>> entries = map.entrySet().iterator();
+ return new Iterator<ConfigurationKey<?>>() {
+ @Override
+ public boolean hasNext() {
+ return entries.hasNext();
+ }
+
+ @Override public ConfigurationKey<?> next() {
+ return new LocalConfigurationKey(entries.next());
+ }
+
+ @Override public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+ }
+
private static void registerKey(String keyName, ConfigurationDataType type) {
synchronized (registeredKeys) {
ConfigurationDataType existingType = registeredKeys.get(keyName);
diff --git a/src/core/lombok/core/configuration/FileSystemSourceCache.java b/src/core/lombok/core/configuration/FileSystemSourceCache.java
index 822a5a2d..3c51fbff 100644
--- a/src/core/lombok/core/configuration/FileSystemSourceCache.java
+++ b/src/core/lombok/core/configuration/FileSystemSourceCache.java
@@ -114,7 +114,7 @@ public class FileSystemSourceCache {
try {
return StringConfigurationSource.forString(fileToString(configFile), reporter);
} catch (Exception e) {
- reporter.report("Exception while reading file: " + e.getMessage());
+ reporter.report("Exception while reading file: " + e.getMessage(), 0, null);
return null;
}
}
diff --git a/src/core/lombok/core/configuration/StringConfigurationSource.java b/src/core/lombok/core/configuration/StringConfigurationSource.java
index 3a6cd9e3..da01b6ee 100644
--- a/src/core/lombok/core/configuration/StringConfigurationSource.java
+++ b/src/core/lombok/core/configuration/StringConfigurationSource.java
@@ -36,17 +36,16 @@ public class StringConfigurationSource implements ConfigurationSource {
private final Map<String, Result<?>> values;
- public static ConfigurationSource forString(String content) {
- return forString(content, ConfigurationErrorReporter.CONSOLE);
- }
-
public static ConfigurationSource forString(String content, ConfigurationErrorReporter reporter) {
if (reporter == null) throw new NullPointerException("reporter");
Map<String, Result<?>> values = new TreeMap<String, Result<?>>(String.CASE_INSENSITIVE_ORDER);
- Map<String, ConfigurationDataType> registeredKeys = ConfigurationKey.registeredKeys();
- for (String line : content.trim().split("\\s*\\n\\s*")) {
+ Map<String, ConfigurationDataType> registeredKeys = ConfigurationKey.registeredKeysAsMap();
+ int lineNumber = 0;
+ for (String line : content.split("\\n")) {
+ line = line.trim();
+ lineNumber++;
if (line.isEmpty() || line.startsWith("#")) continue;
Matcher matcher = LINE.matcher(line);
@@ -66,19 +65,19 @@ public class StringConfigurationSource implements ConfigurationSource {
}
ConfigurationDataType type = registeredKeys.get(keyName);
if (type == null) {
- reporter.report("Unknown key '" + keyName + "' on line: " + line);
+ reporter.report("Unknown key '" + keyName + "'", lineNumber, line);
} else {
boolean listOperator = operator.equals("+=") || operator.equals("-=");
if (listOperator && !type.isList()) {
- reporter.report("'" + keyName + "' is not a list and doesn't support " + operator + " (only = and clear): " + line);
+ reporter.report("'" + keyName + "' is not a list and doesn't support " + operator + " (only = and clear)", lineNumber, line);
} else if (operator.equals("=") && type.isList()) {
- reporter.report("'" + keyName + "' is a list and cannot be assigned to (use +=, -= and clear instead): " + line);
+ reporter.report("'" + keyName + "' is a list and cannot be assigned to (use +=, -= and clear instead)", lineNumber, line);
} else {
- processResult(values, keyName, operator, value, type, reporter);
+ processResult(values, keyName, operator, value, type, reporter, lineNumber, line);
}
}
} else {
- reporter.report("No valid line: " + line);
+ reporter.report("No valid line", lineNumber, line);
}
}
@@ -97,12 +96,12 @@ public class StringConfigurationSource implements ConfigurationSource {
}
}
- private static void processResult(Map<String, Result<?>> values, String keyName, String operator, String value, ConfigurationDataType type, ConfigurationErrorReporter reporter) {
+ private static void processResult(Map<String, Result<?>> values, String keyName, String operator, String value, ConfigurationDataType type, ConfigurationErrorReporter reporter, int lineNumber, String line) {
Object element = null;
if (value != null) try {
element = type.getParser().parse(value);
} catch (Exception e) {
- reporter.report("Error while parsing the value for '" + keyName + "' value '" + value + "' (should be a " + type.getParser().description() + ")");
+ reporter.report("Error while parsing the value for '" + keyName + "' value '" + value + "' (should be a " + type.getParser().description() + ")", lineNumber, line);
return;
}
diff --git a/src/core/lombok/eclipse/handlers/HandlePrintConfiguration.java b/src/core/lombok/eclipse/handlers/HandlePrintConfiguration.java
new file mode 100644
index 00000000..e2bae525
--- /dev/null
+++ b/src/core/lombok/eclipse/handlers/HandlePrintConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.handlers;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
+
+import lombok.Lombok;
+import lombok.core.AnnotationValues;
+import lombok.core.LombokConfiguration;
+import lombok.core.PrintConfiguration;
+import lombok.eclipse.EclipseAnnotationHandler;
+import lombok.eclipse.EclipseNode;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.mangosdk.spi.ProviderFor;
+
+/**
+ * Handles the {@code lombok.core.PrintConfiguration} annotation for eclipse.
+ */
+@ProviderFor(EclipseAnnotationHandler.class)
+public class HandlePrintConfiguration extends EclipseAnnotationHandler<PrintConfiguration> {
+ public void handle(AnnotationValues<PrintConfiguration> annotation, Annotation ast, EclipseNode annotationNode) {
+ PrintStream stream = System.out;
+ String fileName = annotation.getInstance().outfile();
+ if (fileName.length() > 0) try {
+ stream = new PrintStream(new File(fileName));
+ } catch (FileNotFoundException e) {
+ Lombok.sneakyThrow(e);
+ }
+ try {
+ LombokConfiguration.writeConfiguration(annotationNode.getAst(), stream);
+ } finally {
+ if (stream != System.out) {
+ try {
+ stream.close();
+ } catch (Exception e) {
+ Lombok.sneakyThrow(e);
+ }
+ }
+ }
+ }
+}
diff --git a/src/core/lombok/javac/handlers/HandlePrintConfiguration.java b/src/core/lombok/javac/handlers/HandlePrintConfiguration.java
new file mode 100644
index 00000000..dd0ef839
--- /dev/null
+++ b/src/core/lombok/javac/handlers/HandlePrintConfiguration.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.javac.handlers;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
+
+import lombok.Lombok;
+import lombok.core.AnnotationValues;
+import lombok.core.LombokConfiguration;
+import lombok.core.PrintConfiguration;
+import lombok.javac.JavacAnnotationHandler;
+import lombok.javac.JavacNode;
+
+import org.mangosdk.spi.ProviderFor;
+
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+
+/**
+ * Handles the {@code lombok.core.PrintConfiguration} annotation for javac.
+ */
+@ProviderFor(JavacAnnotationHandler.class)
+public class HandlePrintConfiguration extends JavacAnnotationHandler<PrintConfiguration> {
+ @Override public void handle(AnnotationValues<PrintConfiguration> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ PrintStream stream = System.out;
+ String fileName = annotation.getInstance().outfile();
+ if (fileName.length() > 0) try {
+ stream = new PrintStream(new File(fileName));
+ } catch (FileNotFoundException e) {
+ Lombok.sneakyThrow(e);
+ }
+
+ try {
+ LombokConfiguration.writeConfiguration(annotationNode.getAst(), stream);
+ } finally {
+ if (stream != System.out) {
+ try {
+ stream.close();
+ } catch (Exception e) {
+ Lombok.sneakyThrow(e);
+ }
+ }
+ }
+ }
+}