mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 10:18:46 +00:00
[configuration] Added @PrintConfiguration to print the combined interpreted configuration for a certain java file, improved problem reporting
This commit is contained in:
1 parent
610f250c1d
commit
fee535eae9
9 files changed
+270
-27
No files matched your search
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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 "";
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user