aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/ConfigurationKeys.java36
-rw-r--r--src/core/lombok/EqualsAndHashCode.java29
-rw-r--r--src/core/lombok/ToString.java35
-rw-r--r--src/core/lombok/core/AnnotationProcessor.java46
-rw-r--r--src/core/lombok/core/AnnotationValues.java129
-rw-r--r--src/core/lombok/core/LombokNode.java12
-rw-r--r--src/core/lombok/core/Version.java5
-rw-r--r--src/core/lombok/core/configuration/NullCheckExceptionType.java6
-rw-r--r--src/core/lombok/core/handlers/HandlerUtil.java16
-rw-r--r--src/core/lombok/core/handlers/InclusionExclusionUtils.java227
-rw-r--r--src/core/lombok/eclipse/EclipseNode.java71
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java77
-rw-r--r--src/core/lombok/eclipse/handlers/HandleBuilder.java8
-rw-r--r--src/core/lombok/eclipse/handlers/HandleConstructor.java53
-rw-r--r--src/core/lombok/eclipse/handlers/HandleData.java5
-rw-r--r--src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java152
-rw-r--r--src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java135
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java14
-rw-r--r--src/core/lombok/eclipse/handlers/HandleLog.java36
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSetter.java23
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSuperBuilder.java9
-rw-r--r--src/core/lombok/eclipse/handlers/HandleToString.java140
-rw-r--r--src/core/lombok/eclipse/handlers/HandleValue.java3
-rw-r--r--src/core/lombok/eclipse/handlers/HandleWither.java1
-rw-r--r--src/core/lombok/experimental/FieldNameConstants.java40
-rw-r--r--src/core/lombok/extern/apachecommons/CommonsLog.java1
-rw-r--r--src/core/lombok/extern/flogger/Flogger.java62
-rw-r--r--src/core/lombok/extern/java/Log.java1
-rw-r--r--src/core/lombok/extern/jbosslog/JBossLog.java3
-rw-r--r--src/core/lombok/extern/log4j/Log4j.java1
-rw-r--r--src/core/lombok/extern/log4j/Log4j2.java1
-rw-r--r--src/core/lombok/extern/slf4j/Slf4j.java1
-rw-r--r--src/core/lombok/extern/slf4j/XSlf4j.java1
-rw-r--r--src/core/lombok/javac/JavacAST.java124
-rw-r--r--src/core/lombok/javac/JavacNode.java71
-rw-r--r--src/core/lombok/javac/apt/EmptyLombokFileObject.java2
-rw-r--r--src/core/lombok/javac/apt/LombokProcessor.java94
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java9
-rw-r--r--src/core/lombok/javac/handlers/HandleConstructor.java78
-rw-r--r--src/core/lombok/javac/handlers/HandleData.java9
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java145
-rw-r--r--src/core/lombok/javac/handlers/HandleFieldNameConstants.java137
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java14
-rw-r--r--src/core/lombok/javac/handlers/HandleLog.java37
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java13
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java11
-rw-r--r--src/core/lombok/javac/handlers/HandleToString.java120
-rw-r--r--src/core/lombok/javac/handlers/HandleValue.java4
-rw-r--r--src/core/lombok/javac/handlers/HandleWither.java1
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java87
-rw-r--r--src/core9/module-info.java1
-rw-r--r--src/delombok/lombok/delombok/Delombok.java15
-rw-r--r--src/delombok/lombok/delombok/DelombokApp.java2
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java29
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java77
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java19
-rw-r--r--src/eclipseAgent/lombok/launch/PatchFixesHider.java6
-rw-r--r--src/installer/lombok/installer/eclipse/EclipseProductLocationProvider.java11
-rw-r--r--src/utils/lombok/core/ClassLiteral.java13
-rw-r--r--src/utils/lombok/core/FieldSelect.java13
-rw-r--r--src/utils/lombok/eclipse/Eclipse.java22
-rw-r--r--src/utils/lombok/javac/Javac.java21
-rw-r--r--src/website/lombok/website/FetchCurrentVersion.java2
63 files changed, 1944 insertions, 622 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index ade86e27..f5134bbd 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -126,6 +126,13 @@ public class ConfigurationKeys {
public static final ConfigurationKey<FlagUsageType> NO_ARGS_CONSTRUCTOR_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.noArgsConstructor.flagUsage", "Emit a warning or error if @NoArgsConstructor is used.") {};
/**
+ * lombok configuration: {@code lombok.noArgsConstructor.extraPrivate} = {@code true} | {@code false}.
+ *
+ * If {@code true} (default), @Data and @Value will also generate a private no-args constructor, if there isn't already one, setting all fields to their default values.
+ */
+ public static final ConfigurationKey<Boolean> NO_ARGS_CONSTRUCTOR_EXTRA_PRIVATE = new ConfigurationKey<Boolean>("lombok.noArgsConstructor.extraPrivate", "Generate a private no-ars constructor for @Data and @Value (default: true).") {};
+
+ /**
* lombok configuration: {@code lombok.requiredArgsConstructor.flagUsage} = {@code WARNING} | {@code ERROR}.
*
* If set, <em>any</em> usage of {@code @RequiredArgsConstructor} results in a warning / error.
@@ -383,6 +390,13 @@ public class ConfigurationKeys {
public static final ConfigurationKey<FlagUsageType> LOG_JBOSSLOG_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.log.jbosslog.flagUsage", "Emit a warning or error if @JBossLog is used.") {};
/**
+ * lombok configuration: {@code lombok.log.flogger.flagUsage} = {@code WARNING} | {@code ERROR}.
+ *
+ * If set, <em>any</em> usage of {@code @Flogger} results in a warning / error.
+ */
+ public static final ConfigurationKey<FlagUsageType> LOG_FLOGGER_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.log.flogger.flagUsage", "Emit a warning or error if @Flogger is used.") {};
+
+ /**
* lombok configuration: {@code lombok.log.fieldName} = &lt;String: aJavaIdentifier&gt; (Default: {@code log}).
*
* If set the various log annotations (which make a log field) will use the stated identifier instead of {@code log} as a name.
@@ -499,6 +513,28 @@ public class ConfigurationKeys {
*/
public static final ConfigurationKey<FlagUsageType> UTILITY_CLASS_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.utilityClass.flagUsage", "Emit a warning or error if @UtilityClass is used.") {};
+ // ----- FieldNameConstants -----
+ /**
+ * lombok configuration: {@code lombok.fieldNameConstants.flagUsage} = {@code WARNING} | {@code ERROR}.
+ *
+ * If set, <em>any</em> usage of {@code @FieldNameConstants} results in a warning / error.
+ */
+ public static final ConfigurationKey<FlagUsageType> FIELD_NAME_CONSTANTS_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.fieldNameConstants.flagUsage", "Emit a warning or error if @FieldNameConstants is used.") {};
+
+ /**
+ * lombok configuration: {@code lombok.fieldNameConstants.prefix} = &lt;String: aJavaIdentifierPrefix&gt; (Default: {@code PREFIX_}).
+ *
+ * The names of the constants generated by {@code @FieldNameConstants} will be prefixed with this value.
+ */
+ public static final ConfigurationKey<String> FIELD_NAME_CONSTANTS_PREFIX = new ConfigurationKey<String>("lombok.fieldNameConstants.prefix", "names of constants generated by @FieldNameConstants will be prefixed with this value. (default: 'PREFIX_').") {};
+
+ /**
+ * lombok configuration: {@code lombok.fieldNameConstants.suffix} = &lt;String: aJavaIdentifierPrefix&gt; (Default: nothing).
+ *
+ * The names of the constants generated by {@code @FieldNameConstants} will be suffixed with this value.
+ */
+ public static final ConfigurationKey<String> FIELD_NAME_CONSTANTS_SUFFIX = new ConfigurationKey<String>("lombok.fieldNameConstants.suffix", "names of constants generated by @FieldNameConstants will be suffixed with this value. (default: nothing).") {};
+
// ----- Wither -----
/**
diff --git a/src/core/lombok/EqualsAndHashCode.java b/src/core/lombok/EqualsAndHashCode.java
index 2f88ac50..b2fc672d 100644
--- a/src/core/lombok/EqualsAndHashCode.java
+++ b/src/core/lombok/EqualsAndHashCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2017 The Project Lombok Authors.
+ * Copyright (C) 2009-2018 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
@@ -37,6 +37,8 @@ public @interface EqualsAndHashCode {
/**
* Any fields listed here will not be taken into account in the generated {@code equals} and {@code hashCode} implementations.
* Mutually exclusive with {@link #of()}.
+ * <p>
+ * Will soon be marked {@code @Deprecated}; use the {@code @EqualsAndHashCode.Exclude} annotation instead.
*
* @return A list of fields to exclude.
*/
@@ -47,6 +49,8 @@ public @interface EqualsAndHashCode {
* Normally, all non-static, non-transient fields are used for identity.
* <p>
* Mutually exclusive with {@link #exclude()}.
+ * <p>
+ * Will soon be marked {@code @Deprecated}; use the {@code @EqualsAndHashCode.Include} annotation together with {@code @EqualsAndHashCode(onlyExplicitlyIncluded = true)}.
*
* @return A list of fields to use (<em>default</em>: all of them).
*/
@@ -89,4 +93,27 @@ public @interface EqualsAndHashCode {
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
+
+ /**
+ * Only include fields and methods explicitly marked with {@code @EqualsAndHashCode.Include}.
+ * Normally, all (non-static, non-transient) fields are included by default.
+ */
+ boolean onlyExplicitlyIncluded() default false;
+
+ /**
+ * If present, do not include this field in the generated {@code equals} and {@code hashCode} methods.
+ */
+ @Target(ElementType.FIELD)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Exclude {}
+
+ /**
+ * Configure the behaviour of how this member is treated in the {@code equals} and {@code hashCode} implementation; if on a method, include the method's return value as part of calculating hashCode/equality.
+ */
+ @Target({ElementType.FIELD, ElementType.METHOD})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Include {
+ /** Defaults to the method name of the annotated member. If on a method and the name equals the name of a default-included field, this member takes its place. */
+ String replaces() default "";
+ }
}
diff --git a/src/core/lombok/ToString.java b/src/core/lombok/ToString.java
index 0c43c40b..ae3f071f 100644
--- a/src/core/lombok/ToString.java
+++ b/src/core/lombok/ToString.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2017 The Project Lombok Authors.
+ * Copyright (C) 2009-2018 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
@@ -45,6 +45,8 @@ public @interface ToString {
/**
* Any fields listed here will not be printed in the generated {@code toString} implementation.
* Mutually exclusive with {@link #of()}.
+ * <p>
+ * Will soon be marked {@code @Deprecated}; use the {@code @ToString.Exclude} annotation instead.
*
* @return A list of fields to exclude.
*/
@@ -55,6 +57,8 @@ public @interface ToString {
* Normally, all non-static fields are printed.
* <p>
* Mutually exclusive with {@link #exclude()}.
+ * <p>
+ * Will soon be marked {@code @Deprecated}; use the {@code @ToString.Include} annotation together with {@code @ToString(onlyExplicitlyIncluded = true)}.
*
* @return A list of fields to use (<em>default</em>: all of them).
*/
@@ -75,4 +79,33 @@ public @interface ToString {
* @return If {@code true}, always use direct field access instead of calling the getter method.
*/
boolean doNotUseGetters() default false;
+
+ /**
+ * Only include fields and methods explicitly marked with {@code @ToString.Include}.
+ * Normally, all (non-static) fields are included by default.
+ */
+ boolean onlyExplicitlyIncluded() default false;
+
+ /**
+ * If present, do not include this field in the generated {@code toString}.
+ */
+ @Target(ElementType.FIELD)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Exclude {}
+
+ /**
+ * Configure the behaviour of how this member is rendered in the {@code toString}; if on a method, include the method's return value in the output.
+ */
+ @Target({ElementType.FIELD, ElementType.METHOD})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Include {
+// /** If true and the return value is {@code null}, omit this member entirely from the {@code toString} output. */
+// boolean skipNull() default false; // -- We'll add it later, it requires a complete rework on the toString code we generate.
+
+ /** Higher ranks are printed first. Members of the same rank are printed in the order they appear in the source file. */
+ int rank() default 0;
+
+ /** Defaults to the field / method name of the annotated member. If the name equals the name of a default-included field, this member takes its place. */
+ String name() default "";
+ }
}
diff --git a/src/core/lombok/core/AnnotationProcessor.java b/src/core/lombok/core/AnnotationProcessor.java
index 5b4ef393..04448ecb 100644
--- a/src/core/lombok/core/AnnotationProcessor.java
+++ b/src/core/lombok/core/AnnotationProcessor.java
@@ -26,6 +26,7 @@ import static lombok.core.Augments.ClassLoader_lombokAlreadyAddedTo;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
@@ -48,6 +49,7 @@ import lombok.patcher.ClassRootFinder;
@SupportedAnnotationTypes("*")
public class AnnotationProcessor extends AbstractProcessor {
+
private static String trace(Throwable t) {
StringWriter w = new StringWriter();
t.printStackTrace(new PrintWriter(w, true));
@@ -63,6 +65,42 @@ public class AnnotationProcessor extends AbstractProcessor {
private final List<ProcessorDescriptor> registered = Arrays.asList(new JavacDescriptor(), new EcjDescriptor());
private final List<ProcessorDescriptor> active = new ArrayList<ProcessorDescriptor>();
private final List<String> delayedWarnings = new ArrayList<String>();
+
+ /**
+ * This method is a simplified version of {@link lombok.javac.apt.LombokProcessor.getJavacProcessingEnvironment}
+ * It simply returns the processing environment, but in case of gradle incremental compilation,
+ * the delegate ProcessingEnvironment of the gradle wrapper is returned.
+ */
+ public static ProcessingEnvironment getJavacProcessingEnvironment(ProcessingEnvironment procEnv, List<String> delayedWarnings) {
+ ProcessingEnvironment javacProcEnv = tryRecursivelyObtainJavacProcessingEnvironment(procEnv);
+
+ if (javacProcEnv == null) {
+ delayedWarnings.add("Can't get the delegate of the gradle IncrementalProcessingEnvironment.");
+ }
+
+ return javacProcEnv;
+ }
+
+ private static ProcessingEnvironment tryRecursivelyObtainJavacProcessingEnvironment(ProcessingEnvironment procEnv) {
+ if (procEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) {
+ return procEnv;
+ }
+
+ for (Class<?> procEnvClass = procEnv.getClass(); procEnvClass != null; procEnvClass = procEnvClass.getSuperclass()) {
+ try {
+ Field field = procEnvClass.getDeclaredField("delegate");
+ field.setAccessible(true);
+ Object delegate = field.get(procEnv);
+
+ return tryRecursivelyObtainJavacProcessingEnvironment((ProcessingEnvironment) delegate);
+ } catch (final Exception e) {
+ // no valid delegate, try superclass
+ }
+ }
+
+ return null;
+ }
+
static class JavacDescriptor extends ProcessorDescriptor {
private Processor processor;
@@ -72,10 +110,12 @@ public class AnnotationProcessor extends AbstractProcessor {
}
@Override boolean want(ProcessingEnvironment procEnv, List<String> delayedWarnings) {
- if (!procEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) return false;
-
+ ProcessingEnvironment javacProcEnv = getJavacProcessingEnvironment(procEnv, delayedWarnings);
+
+ if (javacProcEnv == null) return false;
+
try {
- ClassLoader classLoader = findAndPatchClassLoader(procEnv);
+ ClassLoader classLoader = findAndPatchClassLoader(javacProcEnv);
processor = (Processor) Class.forName("lombok.javac.apt.LombokProcessor", false, classLoader).newInstance();
} catch (Exception e) {
delayedWarnings.add("You found a bug in lombok; lombok.javac.apt.LombokProcessor is not available. Lombok will not run during this compilation: " + trace(e));
diff --git a/src/core/lombok/core/AnnotationValues.java b/src/core/lombok/core/AnnotationValues.java
index d04797cb..a24330fa 100644
--- a/src/core/lombok/core/AnnotationValues.java
+++ b/src/core/lombok/core/AnnotationValues.java
@@ -27,6 +27,7 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -42,7 +43,7 @@ public class AnnotationValues<A extends Annotation> {
private final Class<A> type;
private final Map<String, AnnotationValue> values;
private final LombokNode<?, ?, ?> ast;
-
+
/**
* Represents a single method on the annotation class. For example, the value() method on the Getter annotation.
*/
@@ -50,8 +51,7 @@ public class AnnotationValues<A extends Annotation> {
/** A list of the raw expressions. List is size 1 unless an array is provided. */
public final List<String> raws;
- /** Guesses for each raw expression. If the raw expression is a literal expression, the guess will
- * likely be right. If not, it'll be wrong. */
+ /** Guesses for each raw expression. It's 'primitive' (String or primitive), an AV.ClassLiteral, an AV.FieldSelect, or an array of one of those. */
public final List<Object> valueGuesses;
/** A list of the actual expressions. List is size 1 unless an array is provided. */
@@ -160,6 +160,62 @@ public class AnnotationValues<A extends Annotation> {
private A cachedInstance = null;
+ public List<String> getAsStringList(String methodName) {
+ AnnotationValue v = values.get(methodName);
+
+ if (v == null) {
+ String[] s = getDefaultIf(methodName, String[].class, new String[0]);
+ return Collections.unmodifiableList(Arrays.asList(s));
+ }
+
+ List<String> out = new ArrayList<String>(v.valueGuesses.size());
+ int idx = 0;
+ for (Object guess : v.valueGuesses) {
+ Object result = guess == null ? null : guessToType(guess, String.class, v, idx);
+ if (result == null) {
+ if (v.valueGuesses.size() == 1) {
+ String[] s = getDefaultIf(methodName, String[].class, new String[0]);
+ return Collections.unmodifiableList(Arrays.asList(s));
+ }
+ throw new AnnotationValueDecodeFail(v,
+ "I can't make sense of this annotation value. Try using a fully qualified literal.", idx);
+ }
+ out.add((String) result);
+ }
+
+ return Collections.unmodifiableList(out);
+ }
+
+ public String getAsString(String methodName) {
+ AnnotationValue v = values.get(methodName);
+ if (v == null || v.valueGuesses.size() != 1) {
+ return getDefaultIf(methodName, String.class, "");
+ }
+
+ Object guess = guessToType(v.valueGuesses.get(0), String.class, v, 0);
+ if (guess instanceof String) return (String) guess;
+ return getDefaultIf(methodName, String.class, "");
+ }
+
+ public boolean getAsBoolean(String methodName) {
+ AnnotationValue v = values.get(methodName);
+ if (v == null || v.valueGuesses.size() != 1) {
+ return getDefaultIf(methodName, boolean.class, false);
+ }
+
+ Object guess = guessToType(v.valueGuesses.get(0), boolean.class, v, 0);
+ if (guess instanceof Boolean) return ((Boolean) guess).booleanValue();
+ return getDefaultIf(methodName, boolean.class, false);
+ }
+
+ public <T> T getDefaultIf(String methodName, Class<T> type, T defaultValue) {
+ try {
+ return type.cast(type.getMethod(methodName).getDefaultValue());
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
/**
* Creates an actual annotation instance. You can use this to query any annotation methods, except for
* those annotation methods with class literals, as those can most likely not be turned into Class objects.
@@ -190,7 +246,7 @@ public class AnnotationValues<A extends Annotation> {
if (!isArray && v.valueGuesses.size() > 1) {
throw new AnnotationValueDecodeFail(v,
- "Expected a single value, but " + method.getName() + " has an array of values", -1);
+ "Expected a single value, but " + method.getName() + " has an array of values", -1);
}
if (v.valueGuesses.size() == 0 && !isArray) {
@@ -217,7 +273,7 @@ public class AnnotationValues<A extends Annotation> {
return defaultValue;
}
throw new AnnotationValueDecodeFail(v,
- "I can't make sense of this annotation value. Try using a fully qualified literal.", idx);
+ "I can't make sense of this annotation value. Try using a fully qualified literal.", idx);
}
Array.set(array, idx++, result);
}
@@ -230,48 +286,48 @@ public class AnnotationValues<A extends Annotation> {
}
private Object guessToType(Object guess, Class<?> expected, AnnotationValue v, int pos) {
- if (expected == int.class) {
+ if (expected == int.class || expected == Integer.class) {
if (guess instanceof Integer || guess instanceof Short || guess instanceof Byte) {
- return ((Number)guess).intValue();
+ return ((Number) guess).intValue();
}
}
- if (expected == long.class) {
+ if (expected == long.class || expected == Long.class) {
if (guess instanceof Long || guess instanceof Integer || guess instanceof Short || guess instanceof Byte) {
- return ((Number)guess).longValue();
+ return ((Number) guess).longValue();
}
}
- if (expected == short.class) {
+ if (expected == short.clas