aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/ConfigurationKeys.java35
-rw-r--r--src/core/lombok/Generated.java6
-rw-r--r--src/core/lombok/Lombok.java12
-rw-r--r--src/core/lombok/Value.java4
-rw-r--r--src/core/lombok/core/AST.java32
-rw-r--r--src/core/lombok/core/AnnotationProcessor.java1
-rw-r--r--src/core/lombok/core/Version.java6
-rw-r--r--src/core/lombok/core/configuration/AllowHelper.java39
-rw-r--r--src/core/lombok/core/configuration/ConfigurationApp.java2
-rw-r--r--src/core/lombok/core/configuration/ConfigurationParser.java4
-rw-r--r--src/core/lombok/core/configuration/FlagUsageType.java2
-rw-r--r--src/core/lombok/core/handlers/HandlerUtil.java15
-rw-r--r--src/core/lombok/eclipse/EclipseAST.java6
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java42
-rw-r--r--src/core/lombok/eclipse/handlers/HandleBuilder.java2
-rw-r--r--src/core/lombok/eclipse/handlers/HandleConstructor.java3
-rw-r--r--src/core/lombok/eclipse/handlers/HandleFieldDefaults.java8
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java6
-rw-r--r--src/core/lombok/eclipse/handlers/HandleLog.java15
-rw-r--r--src/core/lombok/eclipse/handlers/HandleVal.java32
-rw-r--r--src/core/lombok/experimental/FieldDefaults.java4
-rw-r--r--src/core/lombok/experimental/NonFinal.java2
-rw-r--r--src/core/lombok/experimental/PackagePrivate.java2
-rw-r--r--src/core/lombok/experimental/var.java28
-rw-r--r--src/core/lombok/extern/apachecommons/CommonsLog.java1
-rw-r--r--src/core/lombok/extern/java/Log.java1
-rw-r--r--src/core/lombok/extern/jbosslog/JBossLog.java67
-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.java3
-rw-r--r--src/core/lombok/extern/slf4j/XSlf4j.java1
-rw-r--r--src/core/lombok/javac/JavacAST.java42
-rw-r--r--src/core/lombok/javac/apt/LombokProcessor.java8
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java5
-rw-r--r--src/core/lombok/javac/handlers/HandleDelegate.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleFieldDefaults.java8
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java6
-rw-r--r--src/core/lombok/javac/handlers/HandleLog.java13
-rw-r--r--src/core/lombok/javac/handlers/HandleVal.java60
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java39
-rw-r--r--src/delombok/lombok/delombok/FormatPreferences.java2
-rw-r--r--src/delombok/lombok/delombok/PrettyPrinter.java29
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java12
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java75
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java67
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java19
-rw-r--r--src/installer/lombok/installer/IdeLocation.java7
-rw-r--r--src/installer/lombok/installer/IdeLocationProvider.java22
-rw-r--r--src/installer/lombok/installer/Installer.java17
-rw-r--r--src/installer/lombok/installer/InstallerGUI.java10
-rw-r--r--src/installer/lombok/installer/OsUtils.java (renamed from src/installer/lombok/installer/IdeFinder.java)21
-rw-r--r--src/installer/lombok/installer/eclipse/EclipseLocationProvider.java149
-rw-r--r--src/installer/lombok/installer/eclipse/EclipseProductDescriptor.java (renamed from src/installer/lombok/installer/eclipse/STSLocation.java)38
-rw-r--r--src/installer/lombok/installer/eclipse/EclipseProductLocation.java (renamed from src/installer/lombok/installer/eclipse/EclipseLocation.java)55
-rw-r--r--src/installer/lombok/installer/eclipse/EclipseProductLocationProvider.java (renamed from src/installer/lombok/installer/eclipse/EclipseFinder.java)256
-rw-r--r--src/installer/lombok/installer/eclipse/JbdsFinder.java70
-rw-r--r--src/installer/lombok/installer/eclipse/JbdsLocationProvider.java49
-rw-r--r--src/installer/lombok/installer/eclipse/MyEclipseLocationProvider.java (renamed from src/installer/lombok/installer/eclipse/JbdsLocation.java)33
-rw-r--r--src/installer/lombok/installer/eclipse/RhdsLocationProvider.java44
-rw-r--r--src/installer/lombok/installer/eclipse/STSFinder.java70
-rw-r--r--src/installer/lombok/installer/eclipse/STSLocationProvider.java48
-rw-r--r--src/installer/lombok/installer/eclipse/StandardProductDescriptor.java158
-rw-r--r--src/installer/lombok/installer/eclipse/myeclipse.pngbin0 -> 1073 bytes
-rw-r--r--src/installer/lombok/installer/eclipse/rhds.pngbin0 -> 3470 bytes
-rw-r--r--src/launch/lombok/launch/AnnotationProcessor.java14
65 files changed, 1099 insertions, 732 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index 73caf295..ff17ca09 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 The Project Lombok Authors.
+ * Copyright (C) 2013-2017 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
@@ -41,11 +41,32 @@ public class ConfigurationKeys {
/**
* lombok configuration: {@code lombok.addGeneratedAnnotation} = {@code true} | {@code false}.
*
- * If unset or {@code true}, lombok generates {@code @javax.annotation.Generated("lombok")} on all fields, methods, and types that are generated.
+ * If unset or {@code true}, lombok generates various annotations to mark generated code like {@code @javax.annotation.Generated("lombok")} and {@code @lombok.Generated}.
+ *
+ * @see ConfigurationKeys#ADD_JAVAX_GENERATED_ANNOTATIONS
+ * @see ConfigurationKeys#ADD_LOMBOK_GENERATED_ANNOTATIONS
*/
public static final ConfigurationKey<Boolean> ADD_GENERATED_ANNOTATIONS = new ConfigurationKey<Boolean>("lombok.addGeneratedAnnotation", "Generate @javax.annotation.Generated on all generated code (default: true).") {};
/**
+ * lombok configuration: {@code lombok.addJavaxGeneratedAnnotation} = {@code true} | {@code false}.
+ *
+ * If unset or {@code true}, lombok generates {@code @javax.annotation.Generated("lombok")} on all fields, methods, and types that are generated, unless {@code lombok.addGeneratedAnnotation} is set to {@code false}.
+ *
+ * @see ConfigurationKeys#ADD_GENERATED_ANNOTATIONS
+ */
+ public static final ConfigurationKey<Boolean> ADD_JAVAX_GENERATED_ANNOTATIONS = new ConfigurationKey<Boolean>("lombok.addJavaxGeneratedAnnotation", "Generate @javax.annotation.Generated on all generated code (default: follow lombok.addGeneratedAnnotation).") {};
+
+ /**
+ * lombok configuration: {@code lombok.addLombokGeneratedAnnotation} = {@code true} | {@code false}.
+ *
+ * If unset or {@code true}, lombok generates {@code @lombok.Generated} on all fields, methods, and types that are generated, unless {@code lombok.addGeneratedAnnotation} is set to {@code false}.
+ *
+ * @see ConfigurationKeys#ADD_GENERATED_ANNOTATIONS
+ */
+ public static final ConfigurationKey<Boolean> ADD_LOMBOK_GENERATED_ANNOTATIONS = new ConfigurationKey<Boolean>("lombok.addLombokGeneratedAnnotation", "Generate @lombok.Generated on all generated code (default: follow lombok.addGeneratedAnnotation).") {};
+
+ /**
* lombok configuration: {@code lombok.extern.findbugs.addSuppressFBWarnings} = {@code true} | {@code false}.
*
* If {@code true}, lombok generates {@code edu.umd.cs.findbugs.annotations.SuppressFBWarnings} on all fields, methods, and types that are generated.
@@ -283,7 +304,8 @@ public class ConfigurationKeys {
* If set, <em>any</em> usage of {@code val} results in a warning / error.
*/
public static final ConfigurationKey<FlagUsageType> VAL_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.val.flagUsage", "Emit a warning or error if 'val' is used.") {};
-
+ public static final ConfigurationKey<FlagUsageType> VAR_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.var.flagUsage", "Emit a warning or error if 'var' is used.") {};
+
// ##### Extern #####
// ----- Logging -----
@@ -337,6 +359,13 @@ public class ConfigurationKeys {
public static final ConfigurationKey<FlagUsageType> LOG_XSLF4J_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.log.xslf4j.flagUsage", "Emit a warning or error if @XSlf4j is used.") {};
/**
+ * lombok configuration: {@code lombok.log.jbosslog.flagUsage} = {@code WARNING} | {@code ERROR}.
+ *
+ * If set, <em>any</em> usage of {@code @JBossLog} results in a warning / error.
+ */
+ 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.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.
diff --git a/src/core/lombok/Generated.java b/src/core/lombok/Generated.java
index 18411b3d..b99a1b58 100644
--- a/src/core/lombok/Generated.java
+++ b/src/core/lombok/Generated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Project Lombok Authors.
+ * Copyright (C) 2015-2016 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
@@ -27,7 +27,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Lombok will eventually automatically add this annotation to all generated methods, fields, and classes.
+ * Lombok will eventually automatically add this annotation to all generated constructors, methods, fields, and types.
*
* You can mark the presence of this annotation as 'ignore it' for all code style and bug finding tools.
* <p>
@@ -35,7 +35,7 @@ import java.lang.annotation.Target;
* it up so that lombok jars in widespread use start having this, which will make it easier to actually apply it
* later on.
*/
-@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Generated {
}
diff --git a/src/core/lombok/Lombok.java b/src/core/lombok/Lombok.java
index 07fd083d..164c47a8 100644
--- a/src/core/lombok/Lombok.java
+++ b/src/core/lombok/Lombok.java
@@ -71,4 +71,16 @@ public class Lombok {
public static <T> T preventNullAnalysis(T value) {
return value;
}
+
+ /**
+ * Ensures that the {@code value} is not {@code null}.
+ * @param value the value to test for null
+ * @param message the message of the {@link NullPointerException}
+ * @return the value if it is not null
+ * @throws NullPointerException with the {@code message} if the value is null
+ */
+ public static <T> T checkNotNull(T value, String message) {
+ if (value == null) throw new NullPointerException(message);
+ return value;
+ }
}
diff --git a/src/core/lombok/Value.java b/src/core/lombok/Value.java
index 2cecea63..39154226 100644
--- a/src/core/lombok/Value.java
+++ b/src/core/lombok/Value.java
@@ -31,7 +31,7 @@ import java.lang.annotation.Target;
* <p>
* Equivalent to {@code @Getter @FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE) @AllArgsConstructor @ToString @EqualsAndHashCode}.
* <p>
- * Complete documentation is found at <a href="https://projectlombok.org/features/experimental/Value.html">the project lombok features page for &#64;Value</a>.
+ * Complete documentation is found at <a href="https://projectlombok.org/features/Value.html">the project lombok features page for &#64;Value</a>.
*
* @see lombok.Getter
* @see lombok.experimental.FieldDefaults
@@ -49,7 +49,7 @@ public @interface Value {
* We suggest the name: "of", like so:
*
* <pre>
- * public @Data(staticConstructor = "of") class Point { final int x, y; }
+ * public @Value(staticConstructor = "of") class Point { final int x, y; }
* </pre>
*
* Default: No static constructor, instead the normal constructor is public.
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java
index e6efe058..1142018f 100644
--- a/src/core/lombok/core/AST.java
+++ b/src/core/lombok/core/AST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2013 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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,7 @@
*/
package lombok.core;
-import static lombok.Lombok.*;
+import static lombok.Lombok.sneakyThrow;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
@@ -31,10 +31,11 @@ import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import lombok.core.configuration.ConfigurationKey;
import lombok.core.debug.HistogramTracker;
@@ -61,12 +62,18 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
Map<N, N> identityDetector = new IdentityHashMap<N, N>();
private Map<N, L> nodeMap = new IdentityHashMap<N, L>();
private boolean changed = false;
+
+ // The supertypes which are considered AST Node children. Usually, the Statement, and the Expression,
+ // though some platforms (such as Eclipse) group these under one common supertype.
+ private final Collection<Class<? extends N>> statementTypes;
+
private static final HistogramTracker configTracker = System.getProperty("lombok.timeConfig") == null ? null : new HistogramTracker("lombok.config");
- protected AST(String fileName, String packageDeclaration, ImportList imports) {
+ protected AST(String fileName, String packageDeclaration, ImportList imports, Collection<Class<? extends N>> statementTypes) {
this.fileName = fileName == null ? "(unknown).java" : fileName;
this.packageDeclaration = packageDeclaration;
this.imports = imports;
+ this.statementTypes = statementTypes;
}
/**
@@ -209,11 +216,11 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
}
}
- private static Map<Class<?>, Collection<FieldAccess>> fieldsOfASTClasses = new HashMap<Class<?>, Collection<FieldAccess>>();
+ private static final ConcurrentMap<Class<?>, Collection<FieldAccess>> fieldsOfASTClasses = new ConcurrentHashMap<Class<?>, Collection<FieldAccess>>();
/** Returns FieldAccess objects for the stated class. Each field that contains objects of the kind returned by
* {@link #getStatementTypes()}, either directly or inside of an array or java.util.collection (or array-of-arrays,
- * or collection-of-collections, etcetera), is returned.
+ * or collection-of-collections, et cetera), is returned.
*/
protected Collection<FieldAccess> fieldsOf(Class<?> c) {
Collection<FieldAccess> fields = fieldsOfASTClasses.get(c);
@@ -221,8 +228,8 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
fields = new ArrayList<FieldAccess>();
getFields(c, fields);
- fieldsOfASTClasses.put(c, fields);
- return fields;
+ fieldsOfASTClasses.putIfAbsent(c, fields);
+ return fieldsOfASTClasses.get(c);
}
private void getFields(Class<?> c, Collection<FieldAccess> fields) {
@@ -261,13 +268,8 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
return Object.class;
}
- /**
- * The supertypes which are considered AST Node children. Usually, the Statement, and the Expression,
- * though some platforms (such as Eclipse) group these under one common supertype. */
- protected abstract Collection<Class<? extends N>> getStatementTypes();
-
- protected boolean shouldDrill(Class<?> parentType, Class<?> childType, String fieldName) {
- for (Class<?> statementType : getStatementTypes()) {
+ private boolean shouldDrill(Class<?> parentType, Class<?> childType, String fieldName) {
+ for (Class<?> statementType : statementTypes) {
if (statementType.isAssignableFrom(childType)) return true;
}
diff --git a/src/core/lombok/core/AnnotationProcessor.java b/src/core/lombok/core/AnnotationProcessor.java
index ba5fd4f7..5531ad8e 100644
--- a/src/core/lombok/core/AnnotationProcessor.java
+++ b/src/core/lombok/core/AnnotationProcessor.java
@@ -103,7 +103,6 @@ public class AnnotationProcessor extends AbstractProcessor {
URL selfUrl = new File(ClassRootFinder.findClassRootOfClass(AnnotationProcessor.class)).toURI().toURL();
m.invoke(environmentClassLoader, selfUrl);
}
- return environmentClassLoader;
}
ClassLoader ourClassLoader = JavacDescriptor.class.getClassLoader();
diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java
index 549db9e1..4fdb7216 100644
--- a/src/core/lombok/core/Version.java
+++ b/src/core/lombok/core/Version.java
@@ -30,9 +30,9 @@ public class Version {
// ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries).
// Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example.
// Official builds always end in an even number. (Since 0.10.2).
- private static final String VERSION = "1.16.8";
-// private static final String RELEASE_NAME = "Edgy Guinea Pig";
- private static final String RELEASE_NAME = "Candid Duck";
+ private static final String VERSION = "1.16.13";
+ private static final String RELEASE_NAME = "Edgy Guinea Pig";
+// private static final String RELEASE_NAME = "Candid Duck";
private Version() {
//Prevent instantiation
diff --git a/src/core/lombok/core/configuration/AllowHelper.java b/src/core/lombok/core/configuration/AllowHelper.java
new file mode 100644
index 00000000..3873b055
--- /dev/null
+++ b/src/core/lombok/core/configuration/AllowHelper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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.configuration;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import lombok.ConfigurationKeys;
+
+public final class AllowHelper {
+ private final static Collection<? extends ConfigurationKey<?>> ALLOWABLE = Collections.singleton(ConfigurationKeys.VAR_FLAG_USAGE);
+
+ private AllowHelper() {
+ // Prevent instantiation
+ }
+
+ public static boolean isAllowable(ConfigurationKey<?> key) {
+ return ALLOWABLE.contains(key);
+ }
+}
diff --git a/src/core/lombok/core/configuration/ConfigurationApp.java b/src/core/lombok/core/configuration/ConfigurationApp.java
index e441b4de..efe57e38 100644
--- a/src/core/lombok/core/configuration/ConfigurationApp.java
+++ b/src/core/lombok/core/configuration/ConfigurationApp.java
@@ -198,7 +198,7 @@ public class ConfigurationApp extends LombokApp {
if (paths.size() == 1) {
if (!(argsPaths.size() == 1)) out.printf("Configuration for '%s'.%n%n", paths.iterator().next());
} else {
- out.printf("Configuration for:%n", paths.iterator().next());
+ out.printf("Configuration for:%n");
for (String path : paths) out.printf("- %s%n", path);
out.println();
}
diff --git a/src/core/lombok/core/configuration/ConfigurationParser.java b/src/core/lombok/core/configuration/ConfigurationParser.java
index f0a9e142..e80793c1 100644
--- a/src/core/lombok/core/configuration/ConfigurationParser.java
+++ b/src/core/lombok/core/configuration/ConfigurationParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Project Lombok Authors.
+ * Copyright (C) 2014-2016 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
@@ -27,7 +27,7 @@ import java.util.regex.Pattern;
public class ConfigurationParser {
private static final Pattern LINE = Pattern.compile("(?:clear\\s+([^=]+))|(?:(\\S*?)\\s*([-+]?=)\\s*(.*?))");
- private static final Pattern NEWLINE_FINDER = Pattern.compile("^\\s*(.*?)\\s*$", Pattern.MULTILINE);
+ private static final Pattern NEWLINE_FINDER = Pattern.compile("^[\t ]*(.*?)[\t\r ]*$", Pattern.MULTILINE);
private ConfigurationProblemReporter reporter;
diff --git a/src/core/lombok/core/configuration/FlagUsageType.java b/src/core/lombok/core/configuration/FlagUsageType.java
index b7053b7c..8717c22b 100644
--- a/src/core/lombok/core/configuration/FlagUsageType.java
+++ b/src/core/lombok/core/configuration/FlagUsageType.java
@@ -23,5 +23,5 @@ package lombok.core.configuration;
/** Used for lombok configuration to flag usages of certain lombok feature. */
public enum FlagUsageType {
- WARNING, ERROR;
+ WARNING, ERROR, ALLOW;
}
diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java
index a9a4be78..a05578d4 100644
--- a/src/core/lombok/core/handlers/HandlerUtil.java
+++ b/src/core/lombok/core/handlers/HandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2015 The Project Lombok Authors.
+ * Copyright (C) 2013-2017 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
@@ -43,6 +43,7 @@ import lombok.core.AST;
import lombok.core.AnnotationValues;
import lombok.core.JavaIdentifiers;
import lombok.core.LombokNode;
+import lombok.core.configuration.AllowHelper;
import lombok.core.configuration.ConfigurationKey;
import lombok.core.configuration.FlagUsageType;
import lombok.experimental.Accessors;
@@ -97,13 +98,23 @@ public class HandlerUtil {
public static void handleFlagUsage(LombokNode<?, ?, ?> node, ConfigurationKey<FlagUsageType> key, String featureName) {
FlagUsageType fut = node.getAst().readConfiguration(key);
+ if (fut == null && AllowHelper.isAllowable(key)) {
+ node.addError("Use of " + featureName + " is disabled by default. Please add '" + key.getKeyName() + " = " + FlagUsageType.ALLOW + "' to 'lombok.config' if you want to enable is.");
+ }
+
if (fut != null) {
String msg = "Use of " + featureName + " is flagged according to lombok configuration.";
if (fut == FlagUsageType.WARNING) node.addWarning(msg);
- else node.addError(msg);
+ else if (fut == FlagUsageType.ERROR) node.addError(msg);
}
}
+ public static boolean shouldAddGenerated(LombokNode<?, ?, ?> node, ConfigurationKey<Boolean> key) {
+ Boolean add = node.getAst().readConfiguration(key);
+ if (add != null) return add;
+ return !Boolean.FALSE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_GENERATED_ANNOTATIONS));
+ }
+
public static void handleExperimentalFlagUsage(LombokNode<?, ?, ?> node, ConfigurationKey<FlagUsageType> key, String featureName) {
handleFlagUsage(node, key, featureName, ConfigurationKeys.EXPERIMENTAL_FLAG_USAGE, "any lombok.experimental feature");
}
diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java
index 6741b33a..dc2c9843 100644
--- a/src/core/lombok/eclipse/EclipseAST.java
+++ b/src/core/lombok/eclipse/EclipseAST.java
@@ -62,7 +62,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
* @param ast The compilation unit, which serves as the top level node in the tree to be built.
*/
public EclipseAST(CompilationUnitDeclaration ast) {
- super(toFileName(ast), packageDeclaration(ast), new EclipseImportList(ast));
+ super(toFileName(ast), packageDeclaration(ast), new EclipseImportList(ast), statementTypes());
this.compilationUnitDeclaration = ast;
setTop(buildCompilationUnit(ast));
this.completeParse = isComplete(ast);
@@ -477,9 +477,9 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
return putInMap(new EclipseNode(this, statement, childNodes, Kind.STATEMENT));
}
- /** For Eclipse, only Statement counts, as Expression is a subclass of it, even though this isn't
+ /* For Eclipse, only Statement counts, as Expression is a subclass of it, even though this isn't
* entirely correct according to the JLS spec (only some expressions can be used as statements, not all of them). */
- @Override protected Collection<Class<? extends ASTNode>> getStatementTypes() {
+ private static Collection<Class<? extends ASTNode>> statementTypes() {
return Collections.<Class<? extends ASTNode>>singleton(Statement.class);
}
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 0ff5a7f6..f822e095 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2015 The Project Lombok Authors.
+ * Copyright (C) 2009-2017 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
@@ -1168,9 +1168,8 @@ public class EclipseHandlerUtil {
if (params < minArgs || params > maxArgs) continue;
}
- if (def.annotations != null) for (Annotation anno : def.annotations) {
- if (typeMatches(Tolerate.class, node, anno.type)) continue top;
- }
+
+ if (isTolerate(node, def)) continue top;
return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
}
@@ -1181,6 +1180,13 @@ public class EclipseHandlerUtil {
return MemberExistsResult.NOT_EXISTS;
}
+ public static boolean isTolerate(EclipseNode node, AbstractMethodDeclaration def) {
+ if (def.annotations != null) for (Annotation anno : def.annotations) {
+ if (typeMatches(Tolerate.class, node, anno.type)) return true;
+ }
+ return false;
+ }
+
/**
* Checks if there is a (non-default) constructor. In case of multiple constructors (overloading), only
* the first constructor decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
@@ -1194,13 +1200,11 @@ public class EclipseHandlerUtil {
if (node != null && node.get() instanceof TypeDeclaration) {
TypeDeclaration typeDecl = (TypeDeclaration)node.get();
- if (typeDecl.methods != null) top: for (AbstractMethodDeclaration def : typeDecl.methods) {
+ if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) {
if (def instanceof ConstructorDeclaration) {
if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue;
- if (def.annotations != null) for (Annotation anno : def.annotations) {
- if (typeMatches(Tolerate.class, node, anno.type)) continue top;
- }
+ if (isTolerate(node, def)) continue;
return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
}
@@ -1325,6 +1329,7 @@ public class EclipseHandlerUtil {
private static final char[] GENERATED_CODE = "generated code".toCharArray();
private static final char[] LOMBOK = "lombok".toCharArray();
private static final char[][] JAVAX_ANNOTATION_GENERATED = Eclipse.fromQualifiedName("javax.annotation.Generated");
+ private static final char[][] LOMBOK_GENERATED = Eclipse.fromQualifiedName("lombok.Generated");
private static final char[][] EDU_UMD_CS_FINDBUGS_ANNOTATIONS_SUPPRESSFBWARNINGS = Eclipse.fromQualifiedName("edu.umd.cs.findbugs.annotations.SuppressFBWarnings");
public static Annotation[] addSuppressWarningsAll(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) {
@@ -1339,24 +1344,29 @@ public class EclipseHandlerUtil {
}
public static Annotation[] addGenerated(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) {
- if (Boolean.FALSE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_GENERATED_ANNOTATIONS))) return originalAnnotationArray;
- return addAnnotation(source, originalAnnotationArray, JAVAX_ANNOTATION_GENERATED, new StringLiteral(LOMBOK, 0, 0, 0));
+ Annotation[] result = originalAnnotationArray;
+ if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS)) {
+ result = addAnnotation(source, result, JAVAX_ANNOTATION_GENERATED, new StringLiteral(LOMBOK, 0, 0, 0));
+ }
+ if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS)) {
+ result = addAnnotation(source, result, LOMBOK_GENERATED, null);
+ }
+ return result;
}
private static Annotation[] addAnnotation(ASTNode source, Annotation[] originalAnnotationArray, char[][] annotationTypeFqn, ASTNode arg) {
char[] simpleName = annotationTypeFqn[annotationTypeFqn.length - 1];
if (originalAnnotationArray != null) for (Annotation ann : originalAnnotationArray) {
- char[] lastToken = null;
-
if (ann.type instanceof QualifiedTypeReference) {
char[][] t = ((QualifiedTypeReference) ann.type).tokens;
- lastToken = t[t.length - 1];
- } else if (ann.type instanceof SingleTypeReference) {
- lastToken = ((SingleTypeReference) ann.type).token;
+ if (Arrays.deepEquals(t, annotationTypeFqn)) return originalAnnotationArray;
}
- if (lastToken != null && Arrays.equals(simpleName, lastToken)) return originalAnnotationArray;
+ if (ann.type instanceof SingleTypeReference) {
+ char[] lastToken = ((SingleTypeReference) ann.type).token;
+ if (Arrays.equals(lastToken, simpleName)) return originalAnnotationArray;
+ }
}
int pS = source.sourceStart, pE = source.sourceEnd;
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 4e0c4218..afa03538 100644
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -652,7 +652,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
for (int i = 0; i < len; i++) {
if (!(existing[i] instanceof MethodDeclaration)) continue;
char[] existingName = existing[i].selector;
- if (Arrays.equals(name, existingName)) return;
+ if (Arrays.equals(name, existingName) && !isTolerate(fieldNode, existing[i])) return;
}
String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName());
diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java
index 85d1d4ed..a3b0585d 100644
--- a/src/core/lombok/eclipse/handlers/HandleConstructor.java
+++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java
@@ -48,6 +48,7 @@ import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
@@ -381,6 +382,8 @@ public class HandleConstructor {
}
private static Expression getDefaultExpr(TypeReference type, int s, int e) {
+ boolean array = type instanceof ArrayTypeReference;
+ if (array) return new NullLiteral(s, e);
char[] lastToken = type.getLastToken();
if (Arrays.equals(TypeConstants.BOOLEAN, lastToken)) return new FalseLiteral(s, e);
if (Arrays.equals(TypeConstants.CHAR, lastToken)) return new CharLiteral(new char[] {'\'', '\\', '0', '\''}, s, e);
diff --git a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java
index 5ea5a210..702713fe 100644
--- a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java
+++ b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2014 The Project Lombok Authors.
+ * Copyright (C) 2012-2016 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
@@ -97,14 +97,16 @@ public class HandleFieldDefaults extends EclipseASTAdapter {
if (level != null && level != AccessLevel.NONE) {
if ((field.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected)) == 0) {
if (!hasAnnotation(PackagePrivate.class, fieldNode)) {
- field.modifiers |= EclipseHandlerUtil.toEclipseModifier(level);
+ if ((field.modifiers & ClassFileConstants.AccStatic) == 0) {
+ field.modifiers |= EclipseHandlerUtil.toEclipseModifier(level);
+ }
}
}
}
if (makeFinal && (field.modifiers & ClassFileConstants.AccFinal) == 0) {
if (!hasAnnotation(NonFinal.class, fieldNode)) {
- if ((field.modifiers & ClassFileConstants.AccStatic) == 0 || field.initialization != null) {
+ if ((field.modifiers & ClassFileConstants.AccStatic) == 0) {
field.modifiers |= ClassFileConstants.AccFinal;
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index 14f2fb72..77d678f2 100644
--- a/src/core/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2014 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -183,6 +183,10 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
errorNode.addError("'lazy' requires the field to be private and final.");
return;
}
+ if ((field.modifiers & ClassFileConstants.AccTransient) != 0) {
+ errorNode.addError("'lazy' is not supported on transient fields.");
+ return;
+ }
if (field.initialization == null) {
errorNode.addError("'lazy' requires field initialization.");
return;
diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java
index 830190a2..c49030d8 100644
--- a/src/core/lombok/eclipse/handlers/HandleLog.java
+++ b/src/core/lombok/eclipse/handlers/HandleLog.java
@@ -229,6 +229,17 @@ public class HandleLog {
}
}
+ /**
+ * Handles the {@link lombok.extern.jbosslog.JBossLog} annotation for Eclipse.
+ */
+ @ProviderFor(EclipseAnnotationHandler.class)
+ public static class HandleJBossLog extends EclipseAnnotationHandler<lombok.extern.jbosslog.JBossLog> {
+ @Override public void handle(AnnotationValues<lombok.extern.jbosslog.JBossLog> annotation, Annotation source, EclipseNode annotationNode) {
+ handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JBOSSLOG_FLAG_USAGE, "@JBossLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
+ processAnnotation(LoggingFramework.JBOSSLOG, annotation, source, annotationNode, annotation.getInstance().topic());
+ }
+ }
+
enum LoggingFramework {
// private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class);
COMMONS("org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory", "getLog", "@CommonsLog"),
@@ -264,7 +275,9 @@ public class HandleLog {
// private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(TargetType.class);
XSLF4J("org.slf4j.ext.XLogger", "org.slf4j.ext.XLoggerFactory", "getXLogger", "@XSlf4j"),
-
+
+ // private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(TargetType.class);
+ JBOSSLOG("org.jboss.logging.Logger", "org.jboss.logging.Logger", "getLogger", "@JBossLog"),
;
private final String loggerTypeName;
diff --git a/src/core/lombok/eclipse/handlers/HandleVal.java b/src/core/lombok/eclipse/handlers/HandleVal.java
index d4ae417c..d8901067 100644
--- a/src/core/lombok/eclipse/handlers/HandleVal.java
+++ b/src/core/lombok/eclipse/handlers/HandleVal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2014 The Project Lombok Authors.
+ * Copyright (C) 2010-2016 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,8 @@
*/
package lombok.eclipse.handlers;
-import static lombok.core.handlers.HandlerUtil.*;
+import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.typeMatches;
import lombok.ConfigurationKeys;
import lombok.val;
import lombok.core.HandlerPriority;
@@ -29,11 +30,14 @@ import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseASTAdapter;
import lombok.eclipse.EclipseASTVisitor;
import lombok.eclipse.EclipseNode;
+import lombok.experimental.var;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ForStatement;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.mangosdk.spi.ProviderFor;
/*
@@ -44,8 +48,13 @@ import org.mangosdk.spi.ProviderFor;
@HandlerPriority(65536) // 2^16; resolution needs to work, so if the RHS expression is i.e. a call to a generated getter, we have to run after that getter has been generated.
public class HandleVal extends EclipseASTAdapter {
@Override public void visitLocal(EclipseNode localNode, LocalDeclaration local) {
- if (!EclipseHandlerUtil.typeMatches(val.class, localNode, local.type)) return;
- handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
+ TypeReference type = local.type;
+ boolean isVal = typeMatches(val.class, localNode, type);
+ boolean isVar = typeMatches(var.class, localNode, type);
+ if (!(isVal || isVar)) return;
+
+ if (isVal) handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
+ if (isVar) handleFlagUsage(localNode, ConfigurationKeys.VAR_FLAG_USAGE, "var");
boolean variableOfForEach = false;
@@ -54,23 +63,30 @@ public class HandleVal extends EclipseASTAdapter {
variableOfForEach = fs.elementVariable == local;
}
+ String annotation = isVal ? "val" : "var";
if (local.initialization == null && !variableOfForEach) {
- localNode.addError("'val' on a local variable requires an initializer expression");
+ localNode.addError("'" + annotation + "' on a local variable requires an initializer expression");
return;
}
if (local.initialization instanceof ArrayInitializer) {
- localNode.addError("'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
+ localNode.addError("'" + annotation + "' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
return;
}
- if (localNode.directUp().get() instanceof ForStatement) {
+ if (isVal && localNode.directUp().get() instanceof ForStatement) {
localNode.addError("'val' is not allowed in old-style for loops");
return;
}
if (local.initialization != null && local.initialization.getClass().getName().equals("org.eclipse.jdt.internal.compiler.ast.LambdaExpression")) {
- localNode.addError("'val' is not allowed with lambda expressions.");
+ localNode.addError("'" + annotation + "' is not allowed with lambda expressions.");
+ return;
+ }
+
+ if(isVar && local.initialization instanceof NullLiteral) {
+ localNode.addError("variable initializer is 'null'");
+ return;
}
}
}
diff --git a/src/core/lombok/experimental/FieldDefaults.java b/src/core/lombok/experimental/FieldDefaults.java
index dbc4993b..384abda5 100644
--- a/src/core/lombok/experimental/FieldDefaults.java
+++ b/src/core/lombok/experimental/FieldDefaults.java
@@ -33,9 +33,9 @@ import lombok.AccessLevel;
* <p>
* Complete documentation is found at <a href="https://projectlombok.org/features/experimental/FieldDefaults.html">the project lombok features page for &#64;FieldDefaults</a>.
* <p>
- * If {@code makeFinal} is {@code true}, then each field that is not annotated with {@code @NonFinal} will have the {@code final} modifier added.
+ * If {@code makeFinal} is {@code true}, then each (instance) field that is not annotated with {@code @NonFinal} will have the {@code final} modifier added.
* <p>
- * If {@code level} is set, then each field that is package private (i.e. no access modifier) and does not have the {@code @PackagePrivate} annotation will
+ * If {@code level} is set, then each (instance) field that is package private (i.e. no access modifier) and does not have the {@code @PackagePrivate} annotation will
* have the appropriate access level modifier added.
*/
@Target(ElementType.TYPE)
diff --git a/src/core/lombok/experimental/NonFinal.java b/src/core/lombok/experimental/NonFinal.java
index 0c31dd2a..12a45d22 100644
--- a/src/core/lombok/experimental/NonFinal.java
+++ b/src/core/lombok/experimental/NonFinal.java
@@ -28,7 +28,7 @@ import java.lang.annotation.Target;
/**
* Used to indicate the explicit intention for the annotated entity to <em>not</em> be {@code final}.
- * Currently used by {@code FieldDefaults} to avoid having it make a field final.
+ * Currently used by {@code FieldDefaults} and {@code Value} to avoid having it make a field final.
*/
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
diff --git a/src/core/lombok/experimental/PackagePrivate.java b/src/core/lombok/experimental/PackagePrivate.java
index bfe5638b..42002818 100644
--- a/src/core/lombok/experimental/PackagePrivate.java
+++ b/src/core/lombok/experimental/PackagePrivate.java
@@ -28,7 +28,7 @@ import java.lang.annotation.Target;
/**
* Used to indicate the explicit intention for the annotated entity to have the <em>package private</em> access level.
- * Currently used by {@code FieldDefaults} to avoid having it make a field one of {@code public}, {@code protected}, or {@code private}.
+ * Currently used by {@code FieldDefaults} and {@code Value} to avoid having it make a field one of {@code public}, {@code protected}, or {@code private}.
*/
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.SOURCE)
diff --git a/src/core/lombok/experimental/var.java b/src/core/lombok/experimental/var.java
new file mode 100644
index 00000000..d8de8b19
--- /dev/null
+++ b/src/core/lombok/experimental/var.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2010-2013 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.experimental;
+
+/**
+ * like val but not final
+ */
+public @interface var {
+}
diff --git a/src/core/lombok/extern/apachecommons/CommonsLog.java b/src/core/lombok/extern/apachecommons/CommonsLog.java
index 6e64d2d8..777f4b35 100644
--- a/src/core/lombok/extern/apachecommons/CommonsLog.java
+++ b/src/core/lombok/extern/apachecommons/CommonsLog.java
@@ -55,6 +55,7 @@ import java.lang.annotation.Target;
* @see lombok.extern.log4j.Log4j2 &#64;Log4j2
* @see lombok.extern.slf4j.Slf4j &#64;Slf4j
* @see lombok.extern.slf4j.XSlf4j &#64;XSlf4j
+ * @see lombok.extern.jbosslog.JBossLog &#64;JBossLog
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
diff --git a/src/core/lombok/extern/java/Log.java b/src/core/lombok/extern/java/Log.java
index d2cf8c17..d5515283 100644
--- a/src/core/lombok/extern/java/Log.java
+++ b/src/core/lombok/extern/java/Log.java
@@ -54,6 +54,7 @@ import java.lang.annotation.Target;
* @see lombok.extern.log4j.Log4j2 &#64;Log4j2
* @see lombok.extern.slf4j.Slf4j &#64;Slf4j
* @see lombok.extern.slf4j.XSlf4j &#64;XSlf4j
+ * @see lombok.extern.jbosslog.JBossLog &#64;JBossLog
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
diff --git a/src/core/lombok/extern/jbosslog/JBossLog.java b/src/core/lombok/extern/jbosslog/JBossLog.java
new file mode 100644
index 00000000..2735290c
--- /dev/null
+++ b/src/core/lombok/extern/jbosslog/JBossLog.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 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.extern.jbosslog;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Causes lombok to generate a logger field.
+ * <p>
+ * Complete documentation is found at <a href="https://projectlombok.org/features/Log.html">the project lombok features page for lombok log annotations</a>.
+ * <p>
+ * Example:
+ * <pre>
+ * &#64;JBossLog
+ * public class LogExample {
+ * }
+ * </pre>
+ *
+ * will generate:
+ *
+ * <pre>
+ * public class LogExample {
+ * private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
+ * }
+ * </pre>
+ *
+ * This annotation is valid for classes and enumerations.<br />
+ * @see org.jboss.logging.Logger org.jboss.logging.Logger
+ * @see org.jboss.logging.Logger#getLogger(java.lang.Class) org.jboss.logging.Logger.getLogger(Class target)
+ * @see lombok.extern.apachecommons.CommonsLog &#64;CommonsLog
+ * @see lombok.extern.java.Log &#64;Log
+ * @see lombok.extern.log4j.Log4j &#64;Log4j
+ * @see lombok.extern.log4j.Log4j2 &#64;Log4j2
+ * @see lombok.extern.slf4j.XSlf4j &#64;XSlf4j
+ * @see lombok.extern.jbosslog.JBossLog &#64;JBossLog
+ * */
+@Retention(RetentionPolicy.SOURCE)
+@Target(ElementType.TYPE)
+public @interface JBossLog {
+
+ /**
+ * Sets the category of the constructed Logger. By default, it will use the type where the annotation is placed.
+ */
+ String topic() default "";
+}
diff --git a/src/core/lombok/extern/log4j/Log4j.java b/src/core/lombok/extern/log4j/Log4j.java
index 31fedbe7..6c6ef1da 100644
--- a/src/core/lombok/extern/log4j/Log4j.java
+++ b/src/core/lombok/extern/log4j/Log4j.java
@@ -55,6 +55,7 @@ import java.lang.annotation.Target;
* @see lombok.extern.java.Log &#64;Log
* @see lombok.extern.slf4j.Slf4j &#64;Slf4j
* @see lombok.extern.slf4j.XSlf4j &#64;XSlf4j
+ * @see lombok.extern.jbosslog.JBossLog &#64;JBossLog
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
diff --git a/src/core/lombok/extern/log4j/Log4j2.java b/src/core/lombok/extern/log4j/Log4j2.java
index 96d793f7..a1b2e0e7 100644
--- a/src/core/lombok/extern/log4j/Log4j2.java
+++ b/src/core/lombok/extern/log4j/Log4j2.java
@@ -55,6 +55,7 @@ import java.lang.annotation.Target;
* @see lombok.extern.java.Log &#64;Log
* @see lombok.extern.slf4j.Slf4j &#64;Slf4j
* @see lombok.extern.slf4j.XSlf4j &#64;XSlf4j
+ * @see lombok.extern.jbosslog.JBossLog &#64;JBossLog
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
diff --git a/src/core/lombok/extern/slf4j/Slf4j.java b/src/core/lombok/extern/slf4j/Slf4j.java
index 571ebd58..efa6105f 100644
--- a/src/core/lombok/extern/slf4j/Slf4j.java
+++ b/src/core/lombok/extern/slf4j/Slf4j.java
@@ -54,7 +54,8 @@ import java.lang.annotation.Target;
* @see lombok.extern.log4j.Log4j &#64;Log4j
* @see lombok.extern.log4j.Log4j2 &#64;Log4j2
* @see lombok.extern.slf4j.XSlf4j &#64;XSlf4j
- * */
+ * @see lombok.extern.jbosslog.JBossLog &#64;JBossLog
+ */
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Slf4j {
diff --git a/src/core/lombok/extern/slf4j/XSlf4j.java b/src/core/lombok/extern/slf4j/XSlf4j.java
index 369728c4..ce23ab9e 100644
--- a/src/core/lombok/extern/slf4j/XSlf4j.java
+++ b/src/core/lombok/extern/slf4j/XSlf4j.java
@@ -54,6 +54,7 @@ import java.lang.annotation.Target;
* @see lombok.extern.log4j.Log4j &#64;Log4j
* @see lombok.extern.log4j.Log4j2 &#64;Log4j2
* @see lombok.extern.slf4j.Slf4j &#64;Slf4j
+ * @see lombok.extern.jbosslog.JBossLog &#64;JBossLog
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java
index da61361d..106a29ae 100644
--- a/src/core/lombok/javac/JavacAST.java
+++ b/src/core/lombok/javac/JavacAST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2015 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -28,6 +28,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import javax.annotation.processing.Messager;
import javax.tools.Diagnostic;
@@ -79,7 +81,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
* @param top The compilation unit, which serves as the top level node in the tree to be built.
*/
public JavacAST(Messager messager, Context context, JCCompilationUnit top) {
- super(sourceName(top), PackageName.getPackageName(top), new JavacImportList(top));
+ super(sourceName(top), PackageName.getPackageName(top), new JavacImportList(top), statementTypes());
setTop(buildCompilationUnit(top));
this.context = context;
this.messager = messager;
@@ -315,7 +317,6 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
// @Foo int x, y; is handled in javac by putting the same annotation node on 2 JCVariableDecls.
return null;
}
-
return putInMap(new JavacNode(this, annotation, null, Kind.ANNOTATION));
}
@@ -333,12 +334,40 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
if (statement instanceof JCClassDecl) return buildType((JCClassDecl)statement);
if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl)statement, Kind.LOCAL);
if (statement instanceof JCTry) return buildTry((JCTry) statement);
-
+ if (statement.getClass().getSimpleName().equals("JCLambda")) return buildLambda(statement);
if (setAndGetAsHandled(statement)) return null;
return drill(statement);
}
+ private JavacNode buildLambda(JCTree jcTree) {
+ return buildStatementOrExpression(getBody(jcTree));
+ }
+
+ private JCTree getBody(JCTree jcTree) {
+ try {
+ return (JCTree) getBodyMethod(jcTree.getClass()).invoke(jcTree);
+ } catch (Exception e) {
+ throw Javac.sneakyThrow(e);
+ }
+ }
+
+ private final static ConcurrentMap<Class<?>, Method> getBodyMethods = new ConcurrentHashMap<Class<?>, Method>();
+
+ private Method getBodyMethod(Class<?> c) {
+ Method m = getBodyMethods.get(c);
+ if (m != null) {
+ return m;
+ }
+ try {
+ m = c.getMethod("getBody");
+ } catch (NoSuchMethodException e) {
+ throw Javac.sneakyThrow(e);
+ }
+ getBodyMethods.putIfAbsent(c, m);
+ return getBodyMethods.get(c);
+ }
+
private JavacNode drill(JCTree statement) {
try {
List<JavacNode> childNodes = new ArrayList<JavacNode>();
@@ -354,9 +383,8 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
}
}
- /** For javac, both JCExpression and JCStatement are considered as valid children types. */
- @Override
- protected Collection<Class<? extends JCTree>> getStatementTypes() {
+ /* For javac, both JCExpression and JCStatement are considered as valid children types. */
+ private static Collection<Class<? extends JCTree>> statementTypes() {
Collection<Class<? extends JCTree>> collection = new ArrayList<Class<? extends JCTree>>(3);
collection.add(JCStatement.class);
collection.add(JCExpression.class);
diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java
index 128545c7..6547c143 100644
--- a/src/core/lombok/javac/apt/LombokProcessor.java
+++ b/src/core/lombok/javac/apt/LombokProcessor.java
@@ -273,14 +273,12 @@ public class LombokProcessor extends AbstractProcessor {
if (newLevels.isEmpty()) return false;
newLevels.retainAll(priorityLevelsRequiringResolutionReset);
- if (newLevels.isEmpty()) {
- // None of the new levels need resolution, so just keep going.
- continue;
- } else {
+ if (!newLevels.isEmpty()){
// Force a new round to reset resolution. The next round will cause this method (process) to be called again.
forceNewRound((JavacFiler) processingEnv.getFiler());
return false;
}
+ // None of the new levels need resolution, so just keep going.
}
}
@@ -310,6 +308,6 @@ public class LombokProcessor extends AbstractProcessor {
* We just return the latest version of whatever JDK we run on. Stupid? Yeah, but it's either that or warnings on all versions but 1.
*/
@Override public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.values()[SourceVersion.values().length - 1];
+ return SourceVersion.latest();
}
}
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index b83e3d5f..9c3c9d03 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -608,8 +608,9 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
for (JavacNode child : builderType.down()) {
if (child.getKind() != Kind.METHOD) continue;
- Name existingName = ((JCMethodDecl) child.get()).name;
- if (existingName.equals(fieldName)) return;
+ JCMethodDecl methodDecl = (JCMethodDecl) child.get();
+ Name existingName = methodDecl.name;
+ if (existingName.equals(fieldName) && !isTolerate(fieldNode, methodDecl)) return;
}
String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName());
diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java
index 680e7745..49bef769 100644
--- a/src/core/lombok/javac/handlers/HandleDelegate.java
+++ b/src/core/lombok/javac/handlers/HandleDelegate.java
@@ -312,7 +312,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> {
for (TypeMirror param : sig.type.getTypeVariables()) {
Name name = ((TypeVar) param).tsym.name;
- ListBuffer<JCExpression> bounds = types.getBounds((TypeVar) param).isEmpty() ? null : new ListBuffer<JCExpression>();
+ ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
for (Type type : types.getBounds((TypeVar) param)) {
bounds.append(JavacResolution.typeToJCTree(type, annotation.getAst(), true));
}
diff --git a/src/core/lombok/javac/handlers/HandleFieldDefaults.java b/src/core/lombok/javac/handlers/HandleFieldDefaults.java
index 12c22059..52f6c39c 100644
--- a/src/core/lombok/javac/handlers/HandleFieldDefaults.java
+++ b/src/core/lombok/javac/handlers/HandleFieldDefaults.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2015 The Project Lombok Authors.
+ * Copyright (C) 2012-2016 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
@@ -84,14 +84,16 @@ public class HandleFieldDefaults extends JavacASTAdapter {
if (level != null && level != AccessLevel.NONE) {
if ((field.mods.flags & (Flags.PUBLIC | Flags.PRIVATE | Flags.PROTECTED)) == 0) {
if (!hasAnnotationAndDeleteIfNeccessary(PackagePrivate.class, fieldNode)) {
- field.mods.flags |= toJavacModifier(level);
+ if ((field.mods.flags & Flags.STATIC) == 0) {
+ field.mods.flags |= toJavacModifier(level);
+ }
}
}
}
if (makeFinal && (field.mods.flags & Flags.FINAL) == 0) {
if (!hasAnnotationAndDeleteIfNeccessary(NonFinal.class, fieldNode)) {
- if ((field.mods.flags & Flags.STATIC) == 0 || field.init != null) {
+ if ((field.mods.flags & Flags.STATIC) == 0) {
field.mods.flags |= Flags.FINAL;
}
}
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index a330dbc1..0a2fe362 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2014 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -182,6 +182,10 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
source.addError("'lazy' requires the field to be private and final.");
return;
}
+ if ((fieldDecl.mods.flags & Flags.TRANSIENT) != 0) {
+ source.addError("'lazy' is not supported on transient fields.");
+ return;
+ }
if (fieldDecl.init == null) {
source.addError("'lazy' requires field initialization.");
return;
diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java
index 06b7c7ef..d0d709e3 100644
--- a/src/core/lombok/javac/handlers/HandleLog.java
+++ b/src/core/lombok/javac/handlers/HandleLog.java
@@ -175,6 +175,17 @@ public class HandleLog {
}
}
+ /**
+ * Handles the {@link lombok.extern.jbosslog.JBossLog} annotation for javac.
+ */
+ @ProviderFor(JavacAnnotationHandler.class)
+ public static class HandleJBossLog extends JavacAnnotationHandler<lombok.extern.jbosslog.JBossLog> {
+ @Override public void handle(AnnotationValues<lombok.extern.jbosslog.JBossLog> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JBOSSLOG_FLAG_USAGE, "@JBossLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
+ processAnnotation(LoggingFramework.JBOSSLOG, annotation, annotationNode, annotation.getInstance().topic());
+ }
+ }
+
enum LoggingFramework {
// private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class);
COMMONS(lombok.extern.apachecommons.CommonsLog.class, "org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory.getLog"),
@@ -200,6 +211,8 @@ public class HandleLog {
// private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(TargetType.class);
XSLF4J(lombok.extern.slf4j.XSlf4j.class, "org.slf4j.ext.XLogger", "org.slf4j.ext.XLoggerFactory.getXLogger"),
+ // private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(TargetType.class);
+ JBOSSLOG(lombok.extern.jbosslog.JBossLog.class, "org.jboss.logging.Logger", "org.jboss.logging.Logger.getLogger")
;
private final Class<? extends Annotation> annotationClass;
diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java
index 337ab2d7..2976eabe 100644
--- a/src/core/lombok/javac/handlers/HandleVal.java
+++ b/src/core/lombok/javac/handlers/HandleVal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2015 The Project Lombok Authors.
+ * Copyright (C) 2010-2016 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,11 +21,12 @@
*/
package lombok.javac.handlers;
-import static lombok.core.handlers.HandlerUtil.*;
+import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.javac.handlers.JavacHandlerUtil.*;
import lombok.ConfigurationKeys;
import lombok.val;
import lombok.core.HandlerPriority;
+import lombok.experimental.var;
import lombok.javac.JavacASTAdapter;
import lombok.javac.JavacASTVisitor;
import lombok.javac.JavacNode;
@@ -42,6 +43,7 @@ import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCForLoop;
+import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCNewArray;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
@@ -50,21 +52,31 @@ import com.sun.tools.javac.util.List;
@HandlerPriority(65536) // 2^16; resolution needs to work, so if the RHS expression is i.e. a call to a generated getter, we have to run after that getter has been generated.
@ResolutionResetNeeded
public class HandleVal extends JavacASTAdapter {
- @Override public void visitLocal(JavacNode localNode, JCVariableDecl local) {
+
+ private static boolean eq(String typeTreeToString, String key) {
+ return (typeTreeToString.equals(key) || typeTreeToString.equals("lombok." + key));
+ }
+
+ @Override
+ public void visitLocal(JavacNode localNode, JCVariableDecl local) {
JCTree typeTree = local.vartype;
if (typeTree == null) return;
String typeTreeToString = typeTree.toString();
- if (!typeTreeToString.equals("val") && !typeTreeToString.equals("lombok.val")) return;
- if (!typeMatches(val.class, localNode, typeTree)) return;
-
- handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
-
+
+ if (!(eq(typeTreeToString, "val") || eq(typeTreeToString, "var"))) return;
+ boolean isVal = typeMatches(val.class, localNode, typeTree);
+ boolean isVar = typeMatches(var.class, localNode, typeTree);
+ if (!(isVal || isVar)) return;
+
+ if (isVal) handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
+ if (isVar) handleFlagUsage(localNode, ConfigurationKeys.VAR_FLAG_USAGE, "var");
+
JCTree parentRaw = localNode.directUp().get();
- if (parentRaw instanceof JCForLoop) {
+ if (isVal && parentRaw instanceof JCForLoop) {
localNode.addError("'val' is not allowed in old-style for loops");
return;
}
-
+
JCExpression rhsOfEnhancedForLoop = null;
if (local.init == null) {
if (parentRaw instanceof JCEnhancedForLoop) {
@@ -72,21 +84,26 @@ public class HandleVal extends JavacASTAdapter {
if (efl.var == local) rhsOfEnhancedForLoop = efl.expr;
}
}
-
+
+ final String annotation = typeTreeToString;
if (rhsOfEnhancedForLoop == null && local.init == null) {
- localNode.addError("'val' on a local variable requires an initializer expression");
+ localNode.addError("'" + annotation + "' on a local variable requires an initializer expression");
return;
+
}
-
+
if (local.init instanceof JCNewArray && ((JCNewArray)local.init).elemtype == null) {
- localNode.addError("'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
+ localNode.addError("'" + annotation + "' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
return;
}
-
- if (localNode.shouldDeleteLombokAnnotations()) JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, "lombok.val");
-
- local.mods.flags |= Flags.FINAL;
-
+
+ if (localNode.shouldDeleteLombokAnnotations()) {
+ JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, val.class.getName());
+ JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, var.class.getName());
+ }
+
+ if (isVal) local.mods.flags |= Flags.FINAL;
+
if (!localNode.shouldDeleteLombokAnnotations()) {
JCAnnotation valAnnotation = recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), typeTree, localNode.getContext());
local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation);
@@ -102,6 +119,9 @@ public class HandleVal extends JavacASTAdapter {
try {
if (rhsOfEnhancedForLoop == null) {
if (local.init.type == null) {
+ if (isVar && local.init instanceof JCLiteral && ((JCLiteral) local.init).value == null) {
+ localNode.addError("variable initializer is 'null'");
+ }
JavacResolution resolver = new JavacResolution(localNode.getContext());
try {
type = ((JCExpression) resolver.resolveMethodMember(localNode).get(local.init)).type;
@@ -149,7 +169,7 @@ public class HandleVal extends JavacASTAdapter {
}
localNode.getAst().setChanged();
} catch (JavacResolution.TypeNotConvertibleException e) {
- localNode.addError("Cannot use 'val' here because initializer expression does not have a representable type: " + e.getMessage());
+ localNode.addError("Cannot use '" + annotation + "' here because initializer expression does not have a representable type: " + e.getMessage());
local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
}
} catch (RuntimeException e) {
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index fdc8a262..1ea3fa92 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2015 The Project Lombok Authors.
+ * Copyright (C) 2009-2017 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
@@ -605,10 +605,7 @@ public class JavacHandlerUtil {
if (params < minArgs || params > maxArgs) continue;
}
- List<JCAnnotation> annotations = md.getModifiers().getAnnotations();
- if (annotations != null) for (JCAnnotation anno : annotations) {
- if (typeMatches(Tolerate.class, node, anno.getAnnotationType())) continue top;
- }
+ if (isTolerate(node, md)) continue top;
return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
}
@@ -619,6 +616,14 @@ public class JavacHandlerUtil {
return MemberExistsResult.NOT_EXISTS;
}
+ public static boolean isTolerate(JavacNode node, JCTree.JCMethodDecl md) {
+ List<JCAnnotation> annotations = md.getModifiers().getAnnotations();
+ if (annotations != null) for (JCTree.JCAnnotation anno : annotations) {
+ if (typeMatches(Tolerate.class, node, anno.getAnnotationType())) return true;
+ }
+ return false;
+ }
+
/**
* Checks if there is a (non-default) constructor. In case of multiple constructors (overloading), only
* the first constructor decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
@@ -629,15 +634,12 @@ public class JavacHandlerUtil {
node = upToTypeNode(node);
if (node != null && node.get() instanceof JCClassDecl) {
- top: for (JCTree def : ((JCClassDecl)node.get()).defs) {
+ for (JCTree def : ((JCClassDecl)node.get()).defs) {
if (def instanceof JCMethodDecl) {
JCMethodDecl md = (JCMethodDecl) def;
if (md.name.contentEquals("<init>")) {
if ((md.mods.flags & Flags.GENERATEDCONSTR) != 0) continue;
- List<JCAnnotation> annotations = md.getModifiers().getAnnotations();
- if (annotations != null) for (JCAnnotation anno : annotations) {
- if (typeMatches(Tolerate.class, node, anno.getAnnotationType())) continue top;
- }
+ if (isTolerate(node, md)) continue;
return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
}
}
@@ -997,9 +999,12 @@ public class JavacHandlerUtil {
public static void addGenerated(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context) {
if (!LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateGenerated()) return;
- if (!Boolean.FALSE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_GENERATED_ANNOTATIONS))) {
+ if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS)) {
addAnnotation(mods, node, pos, source, context, "javax.annotation.Generated", node.getTreeMaker().Literal("lombok"));
}
+ if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS)) {
+ addAnnotation(mods, node, pos, source, context, "lombok.Generated", null);
+ }
}
private static void addAnnotation(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context, String annotationTypeFqn, JCExpression arg) {
@@ -1013,12 +1018,16 @@ public class JavacHandlerUtil {
for (JCAnnotation ann : mods.annotations) {
JCTree annType = ann.getAnnotationType();
- Name lastPart = null;
- if (annType instanceof JCIdent) lastPart = ((JCIdent) annType).name;
- else if (annType instanceof JCFieldAccess) lastPart = ((JCFieldAccess) annType).name;
+ if (annType instanceof JCIdent) {
+ Name lastPart = ((JCIdent) annType).name;
+ if (lastPart.contentEquals(simpleName)) return;
+ }
- if (lastPart != null && lastPart.contentEquals(simpleName)) return;
+ if (annType instanceof JCFieldAccess) {
+ if (annType.toString().equals(annotationTypeFqn)) return;
+ }
}
+
JavacTreeMaker maker = node.getTreeMaker();
JCExpression annType = isJavaLangBased ? genJavaLangTypeRef(node, simpleName) : chainDotsString(node, annotationTypeFqn);
annType.pos = pos;
diff --git a/src/delombok/lombok/delombok/FormatPreferences.java b/src/delombok/lombok/delombok/FormatPreferences.java
index 5ba3b8cd..3861685d 100644
--- a/src/delombok/lombok/delombok/FormatPreferences.java
+++ b/src/delombok/lombok/delombok/FormatPreferences.java
@@ -44,7 +44,7 @@ public final class FormatPreferences {
keys.put("finalParams", "Either 'generate' or 'skip'. generate means: All lombok-generated methods set all parameters to final. Default: 'generate'");
keys.put("constructorProperties", "Either 'generate' or 'skip'. generate means: All lombok-generated constructors with 1 or more arguments get an @ConstructorProperties annotation. Default: 'generate'");
keys.put("suppressWarnings", "Either 'generate' or 'skip'. generate means: All lombok-generated methods, types, and fields get a @SuppressWarnings annotation. Default: 'generate'");
- keys.put("generated", "Either 'generate' or 'skip'. generate means: All lombok-generated methods, types, and fields get a @Generated(\"lombok\") annotation. Default: 'generate'");
+ keys.put("generated", "Either 'generate' or 'skip'. generate means: All lombok-generated methods, types, and fields get a @javax.annotation.Generated(\"lombok\") annotation. Default: 'generate'");
keys.put("danceAroundIdeChecks", "Either 'generate' or 'skip'. generate means: Lombok will intentionally obfuscate some generated code to avoid IDE warnings. Default: 'generate'");
keys.put("generateDelombokComment", "Either 'generate' or 'skip'. generate means: Any file modified by delombok will have a comment stating this at the top. Default: 'generate'");
keys.put("javaLangAsFQN", "Either 'generate' or 'skip'. generate means: Any generated reference to java.lang classes are prefixed with `java.lang.`. Default: 'generate'");
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index 73d6ee90..b5064a33 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2016 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.delombok;
import static com.sun.tools.javac.code.Flags.*;
@@ -1054,6 +1075,7 @@ public class PrettyPrinter extends JCTree.Visitor {
@Override public void visitForLoop(JCForLoop tree) {
aPrint("for (");
if (tree.init.nonEmpty()) {
+ // ForInit is either a StatementExpressionList or a LocalVariableDeclaration
if (tree.init.head instanceof JCVariableDecl) {
boolean first = true;
int dims = 0;
@@ -1075,7 +1097,12 @@ public class PrettyPrinter extends JCTree.Visitor {
first = false;
}
} else {
- print(tree.init, ", ");
+ boolean first = true;
+ for (JCStatement exprStatement : tree.init) {
+ if (!first) print(", ");
+ first = false;
+ print(((JCExpressionStatement) exprStatement).expr);
+ }
}
}
print("; ");
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 336204a2..77f615b5 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -24,6 +24,8 @@ package lombok.eclipse.agent;
import static lombok.patcher.scripts.ScriptBuilder.*;
import java.lang.instrument.Instrumentation;
+import java.net.URLClassLoader;
+import java.security.ProtectionDomain;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -31,6 +33,7 @@ import java.util.List;
import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
import lombok.core.AgentLauncher;
+import lombok.patcher.Filter;
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
import lombok.patcher.ScriptManager;
@@ -76,6 +79,15 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses, boolean ecjOnly, Class<?> launchingContext) {
ScriptManager sm = new ScriptManager();
sm.registerTransformer(instrumentation);
+ sm.setFilter(new Filter() {
+ @Override public boolean shouldTransform(ClassLoader loader, String className, Class<?> classBeingDefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
+ if (!(loader instanceof URLClassLoader)) return true;
+ ClassLoader parent = loader.getParent();
+ if (parent == null) return true;
+ return !parent.getClass().getName().startsWith("org.eclipse.jdt.apt.core.internal.AnnotationProcessorFactoryLoader");
+ }
+ });
+
final boolean forceBaseResourceNames = !"".equals(System.getProperty("shadow.override.lombok", ""));
sm.setTransplantMapper(new TransplantMapper() {
public String mapResourceName(int classFileFormatVersion, String resourceName) {
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
index b1f5a43a..02760e35 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
@@ -699,7 +699,10 @@ public class PatchDelegate {
}
private static void addAllMethodBindings0(List<BindingTuple> list, TypeBinding binding, Set<String> banList, char[] fieldName, ASTNode responsible) throws DelegateRecursion {
- if (binding instanceof SourceTypeBinding) ((SourceTypeBinding) binding).scope.environment().globalOptions.storeAnnotations = true;
+ if (binding instanceof SourceTypeBinding) {
+ ClassScope scope = ((SourceTypeBinding) binding).scope;
+ if (scope != null) scope.environment().globalOptions.storeAnnotations = true;
+ }
if (binding == null) return;
TypeBinding inner;
@@ -721,42 +724,44 @@ public class PatchDelegate {
}
}
- if (binding instanceof ReferenceBinding) {
- ReferenceBinding rb = (ReferenceBinding) binding;
- MethodBinding[] availableMethods = rb.availableMethods();
- FieldBinding[] availableFields = rb.availableFields();
- failIfContainsAnnotation(binding, availableMethods);
- failIfContainsAnnotation(binding, availableFields);
-
- MethodBinding[] parameterizedSigs = availableMethods;
- MethodBinding[] baseSigs = parameterizedSigs;
- if (binding instanceof ParameterizedTypeBinding) {
- baseSigs = ((ParameterizedTypeBinding)binding).genericType().availableMethods();
- if (baseSigs.length != parameterizedSigs.length) {
- // The last known state of eclipse source says this can't happen, so we rely on it,
- // but if this invariant is broken, better to go with 'arg0' naming instead of crashing.
- baseSigs = parameterizedSigs;
- }
- }
- for (int i = 0; i < parameterizedSigs.length; i++) {
- MethodBinding mb = parameterizedSigs[i];
- String sig = printSig(mb);
- if (mb.isStatic()) continue;
- if (mb.isBridge()) continue;
- if (mb.isConstructor()) continue;
- if (mb.isDefaultAbstract()) continue;
- if (!mb.isPublic()) continue;
- if (mb.isSynthetic()) continue;
- if (!banList.add(sig)) continue; // If add returns false, it was already in there.
- BindingTuple pair = new BindingTuple(mb, baseSigs[i], fieldName, responsible);
- list.add(pair);
- }
- addAllMethodBindings0(list, rb.superclass(), banList, fieldName, responsible);
- ReferenceBinding[] interfaces = rb.superInterfaces();
- if (interfaces != null) {
- for (ReferenceBinding iface : interfaces) addAllMethodBindings0(list, iface, banList, fieldName, responsible);
+ if (!(binding instanceof ReferenceBinding)) {
+ return;
+ }
+
+ ReferenceBinding rb = (ReferenceBinding) binding;
+ MethodBinding[] availableMethods = rb.availableMethods();
+ FieldBinding[] availableFields = rb.availableFields();
+ failIfContainsAnnotation(binding, availableMethods);
+ failIfContainsAnnotation(binding, availableFields);
+
+ MethodBinding[] parameterizedSigs = availableMethods;
+ MethodBinding[] baseSigs = parameterizedSigs;
+ if (binding instanceof ParameterizedTypeBinding) {
+ baseSigs = ((ParameterizedTypeBinding)binding).genericType().availableMethods();
+ if (baseSigs.length != parameterizedSigs.length) {
+ // The last known state of eclipse source says this can't happen, so we rely on it,
+ // but if this invariant is broken, better to go with 'arg0' naming instead of crashing.
+ baseSigs = parameterizedSigs;
}
}
+ for (int i = 0; i < parameterizedSigs.length; i++) {
+ MethodBinding mb = parameterizedSigs[i];
+ String sig = printSig(mb);
+ if (mb.isStatic()) continue;
+ if (mb.isBridge()) continue;
+ if (mb.isConstructor()) continue;
+ if (mb.isDefaultAbstract()) continue;
+ if (!mb.isPublic()) continue;
+ if (mb.isSynthetic()) continue;
+ if (!banList.add(sig)) continue; // If add returns false, it was already in there.
+ BindingTuple pair = new BindingTuple(mb, baseSigs[i], fieldName, responsible);
+ list.add(pair);
+ }
+ addAllMethodBindings0(list, rb.superclass(), banList, fieldName, responsible);
+ ReferenceBinding[] interfaces = rb.superInterfaces();
+ if (interfaces != null) {
+ for (ReferenceBinding iface : interfaces) addAllMethodBindings0(list, iface, banList, fieldName, responsible);
+ }
}
private static final char[] STRING_LOMBOK = new char[] {'l', 'o', 'm', 'b', 'o', 'k'};
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index 2b8dfbaa..e4dd7b26 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -21,11 +21,6 @@
*/
package lombok.eclipse.agent;
-import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
-import static lombok.eclipse.Eclipse.*;
-
-import java.lang.reflect.Field;
-
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
@@ -43,6 +38,11 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import java.lang.reflect.Field;
+
+import static lombok.eclipse.Eclipse.poss;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.makeType;
+
public class PatchVal {
// This is half of the work for 'val' support - the other half is in PatchValEclipse. This half is enough for ecj.
@@ -84,31 +84,44 @@ public class PatchVal {
return true;
}
- public static boolean couldBeVal(TypeReference ref) {
+ public static boolean couldBe(String key, TypeReference ref) {
+ String[] keyParts = key.split("\\.");
if (ref instanceof SingleTypeReference) {
char[] token = ((SingleTypeReference)ref).token;
- return matches("val", token);
+ return matches(keyParts[keyParts.length - 1], token);
}
if (ref instanceof QualifiedTypeReference) {
char[][] tokens = ((QualifiedTypeReference)ref).tokens;
- if (tokens == null || tokens.length != 2) return false;
- return matches("lombok", tokens[0]) && matches("val", tokens[1]);
+ if (keyParts.length != tokens.length) return false;
+ for(int i = 0; i < tokens.length; ++i) {
+ String part = keyParts[i];
+ char[] token = tokens[i];
+ if (!matches(part, token)) return false;
+ }
+ return true;
}
return false;
}
-
- private static boolean isVal(TypeReference ref, BlockScope scope) {
- if (!couldBeVal(ref)) return false;
-
+
+ private static boolean is(TypeReference ref, BlockScope scope, String key) {
+ if (!couldBe(key, ref)) return false;
+
TypeBinding resolvedType = ref.resolvedType;
if (resolvedType == null) resolvedType = ref.resolveType(scope, false);
if (resolvedType == null) return false;
char[] pkg = resolvedType.qualifiedPackageName();
char[] nm = resolvedType.qualifiedSourceName();
- return matches("lombok", pkg) && matches("val", nm);
+ int pkgFullLength = pkg.length > 0 ? pkg.length + 1: 0;
+ char[] fullName = new char[pkgFullLength + nm.length];
+ if(pkg.length > 0) {
+ System.arraycopy(pkg, 0, fullName, 0, pkg.length);
+ fullName[pkg.length] = '.';
+ }
+ System.arraycopy(nm, 0, fullName, pkgFullLength, nm.length);
+ return matches(key, fullName);
}
public static final class Reflection {
@@ -132,13 +145,17 @@ public class PatchVal {
if (local == null || !LocalDeclaration.class.equals(local.getClass())) return false;
boolean decomponent = false;
- if (!isVal(local.type, scope)) return false;
+ boolean val = isVal(local, scope);
+ boolean var = isVar(local, scope);
+ if (!(val || var)) return false;
StackTraceElement[] st = new Throwable().getStackTrace();
for (int i = 0; i < st.length - 2 && i < 10; i++) {
if (st[i].getClassName().equals("lombok.launch.PatchFixesHider$Val")) {
- if (st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") &&
- st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement")) return false;
+ boolean valInForStatement = val &&
+ st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") &&
+ st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement");
+ if (valInForStatement) return false;
break;
}
}
@@ -187,23 +204,33 @@ public class PatchVal {
}
}
- local.modifiers |= ClassFileConstants.AccFinal;
+ if(val) local.modifiers |= ClassFileConstants.AccFinal;
local.annotations = addValAnnotation(local.annotations, local.type, scope);
local.type = replacement != null ? replacement : new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(local.type, 3));
return false;
}
+ private static boolean isVar(LocalDeclaration local, BlockScope scope) {
+ return is(local.type, scope, "lombok.experimental.var");
+ }
+
+ private static boolean isVal(LocalDeclaration local, BlockScope scope) {
+ return is(local.type, scope, "lombok.val");
+ }
+
public static boolean handleValForForEach(ForeachStatement forEach, BlockScope scope) {
if (forEach.elementVariable == null) return false;
- if (!isVal(forEach.elementVariable.type, scope)) return false;
+ boolean val = isVal(forEach.elementVariable, scope);
+ boolean var = isVar(forEach.elementVariable, scope);
+ if (!(val || var)) return false;
TypeBinding component = getForEachComponentType(forEach.collection, scope);
if (component == null) return false;
TypeReference replacement = makeType(component, forEach.elementVariable.type, false);
- forEach.elementVariable.modifiers |= ClassFileConstants.AccFinal;
+ if (val) forEach.elementVariable.modifiers |= ClassFileConstants.AccFinal;
forEach.elementVariable.annotations = addValAnnotation(forEach.elementVariable.annotations, forEach.elementVariable.type, scope);
forEach.elementVariable.type = replacement != null ? replacement :
new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(forEach.elementVariable.type, 3));
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
index 7d5f36f4..505eb767 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
@@ -47,6 +47,7 @@ import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.parser.Parser;
@@ -65,7 +66,9 @@ public class PatchValEclipse {
ForeachStatement foreachDecl = (ForeachStatement) astStack[astPtr];
ASTNode init = foreachDecl.collection;
if (init == null) return;
- if (foreachDecl.elementVariable == null || !PatchVal.couldBeVal(foreachDecl.elementVariable.type)) return;
+ boolean val = couldBeVal(foreachDecl.elementVariable.type);
+ boolean var = couldBeVar(foreachDecl.elementVariable.type);
+ if (foreachDecl.elementVariable == null || !(val || var)) return;
try {
if (Reflection.iterableCopyField != null) Reflection.iterableCopyField.set(foreachDecl.elementVariable, init);
@@ -88,7 +91,9 @@ public class PatchValEclipse {
if (!(variableDecl instanceof LocalDeclaration)) return;
ASTNode init = variableDecl.initialization;
if (init == null) return;
- if (!PatchVal.couldBeVal(variableDecl.type)) return;
+ boolean val = couldBeVal(variableDecl.type);
+ boolean var = couldBeVar(variableDecl.type);
+ if (!(val || var)) return;
try {
if (Reflection.initCopyField != null) Reflection.initCopyField.set(variableDecl, init);
@@ -97,6 +102,10 @@ public class PatchValEclipse {
}
}
+ private static boolean couldBeVar(TypeReference type) {
+ return PatchVal.couldBe("lombok.experimental.var", type);
+ }
+
public static void addFinalAndValAnnotationToSingleVariableDeclaration(Object converter, SingleVariableDeclaration out, LocalDeclaration in) {
@SuppressWarnings("unchecked") List<IExtendedModifier> modifiers = out.modifiers();
addFinalAndValAnnotationToModifierList(converter, modifiers, out.getAST(), in);
@@ -115,7 +124,7 @@ public class PatchValEclipse {
Annotation valAnnotation = null;
for (Annotation ann : in.annotations) {
- if (PatchVal.couldBeVal(ann.type)) {
+ if (couldBeVal(ann.type)) {
found = true;
valAnnotation = ann;
break;
@@ -167,6 +176,10 @@ public class PatchValEclipse {
}
}
+ private static boolean couldBeVal(TypeReference type) {
+ return PatchVal.couldBe("lombok.val", type);
+ }
+
public static Modifier createModifier(AST ast, ModifierKeyword keyword, int start, int end) {
Modifier modifier = null;
try {
diff --git a/src/installer/lombok/installer/IdeLocation.java b/src/installer/lombok/installer/IdeLocation.java
index 4e3a7e41..c3853867 100644
--- a/src/installer/lombok/installer/IdeLocation.java
+++ b/src/installer/lombok/installer/IdeLocation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2014 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -25,7 +25,6 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
-import lombok.installer.eclipse.EclipseFinder;
import lombok.patcher.ClassRootFinder;
/**
@@ -46,7 +45,7 @@ public abstract class IdeLocation {
* a jar that wasn't accessed via the file-system, or if its started via e.g. unpacking the jar.
*/
public static File findOurJar() {
- return new File(ClassRootFinder.findClassRootOfClass(IdeFinder.class));
+ return new File(ClassRootFinder.findClassRootOfClass(OsUtils.class));
}
@Override public String toString() {
@@ -70,7 +69,7 @@ public abstract class IdeLocation {
private static final String LEGAL_PATH_CHARS_WINDOWS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/:\\ ";
public static String escapePath(String path) {
StringBuilder out = new StringBuilder();
- String legalChars = IdeFinder.getOS() == EclipseFinder.OS.UNIX ? LEGAL_PATH_CHARS : LEGAL_PATH_CHARS_WINDOWS;
+ String legalChars = OsUtils.getOS() == OsUtils.OS.UNIX ? LEGAL_PATH_CHARS : LEGAL_PATH_CHARS_WINDOWS;
for (char c : path.toCharArray()) {
if (legalChars.indexOf(c) == -1) out.append('\\');
out.append(c);
diff --git a/src/installer/lombok/installer/IdeLocationProvider.java b/src/installer/lombok/installer/IdeLocationProvider.java
index 933a5989..c4b64141 100644
--- a/src/installer/lombok/installer/IdeLocationProvider.java
+++ b/src/installer/lombok/installer/IdeLocationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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,20 +21,30 @@
*/
package lombok.installer;
+import java.util.List;
import java.util.regex.Pattern;
-import lombok.installer.IdeFinder.OS;
-
public interface IdeLocationProvider {
/**
* @throws CorruptedIdeLocationException
* Only throw this exception if the location seems like a proper installation except there's something wrong with it.
* Do not throw it (just return {@code null}) if there's nothing there or it looks absolutely nothing like your IDE.
*/
- public abstract IdeLocation create(String path) throws CorruptedIdeLocationException;
+ IdeLocation create(String path) throws CorruptedIdeLocationException;
+
+ /**
+ * Return the usual name of the IDE executable or other obvious marker of an IDE installation on the current platform.
+ */
+ Pattern getLocationSelectors();
/**
- * Return the usual name of the IDE executable or other obvious marker of an IDE installation on the provided platform.
+ * Look for installations of your IDE in the usual places.
+ *
+ * @param locations Add to this list any valid locations that you found.
+ * @param problems
+ * Add to this list any locations that look like installations,
+ * but have problems that prevent you from installing/uninstalling from them. DONT add to this list
+ * any common locations that have no installation at all - only add near misses.
*/
- public abstract Pattern getLocationSelectors(OS os);
+ void findIdes(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems);
}
diff --git a/src/installer/lombok/installer/Installer.java b/src/installer/lombok/installer/Installer.java
index 7ae01d7a..94cc1a45 100644
--- a/src/installer/lombok/installer/Installer.java
+++ b/src/installer/lombok/installer/Installer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2010 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -38,7 +38,7 @@ import lombok.Lombok;
import lombok.core.LombokApp;
import lombok.core.SpiLoadUtil;
import lombok.core.Version;
-import lombok.installer.IdeFinder.OS;
+import lombok.installer.OsUtils.OS;
import lombok.patcher.ClassRootFinder;
import org.mangosdk.spi.ProviderFor;
@@ -72,10 +72,9 @@ public class Installer {
}
static List<Pattern> getIdeExecutableNames() {
- OS os = IdeFinder.getOS();
List<Pattern> list = new ArrayList<Pattern>();
for (IdeLocationProvider provider : locationProviders) {
- Pattern p = provider.getLocationSelectors(os);
+ Pattern p = provider.getLocationSelectors();
if (p != null) list.add(p);
}
return list;
@@ -91,12 +90,8 @@ public class Installer {
}
static void autoDiscover(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
- try {
- for (IdeFinder finder : SpiLoadUtil.findServices(IdeFinder.class)) {
- finder.findIdes(locations, problems);
- }
- } catch (IOException e) {
- throw Lombok.sneakyThrow(e);
+ for (IdeLocationProvider provider : locationProviders) {
+ provider.findIdes(locations, problems);
}
}
@@ -160,7 +155,7 @@ public class Installer {
}
private static int guiInstaller() {
- if (IdeFinder.getOS() == OS.MAC_OS_X) {
+ if (OsUtils.getOS() == OS.MAC_OS_X) {
System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Lombok Installer");
System.setProperty("com.apple.macos.use-file-dialog-packages", "true");
}
diff --git a/src/installer/lombok/installer/InstallerGUI.java b/src/installer/lombok/installer/InstallerGUI.java
index 6b8a58ab..ebdf2035 100644
--- a/src/installer/lombok/installer/InstallerGUI.java
+++ b/src/installer/lombok/installer/InstallerGUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2010 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -67,7 +67,7 @@ import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import lombok.core.Version;
-import lombok.installer.IdeFinder.OS;
+import lombok.installer.OsUtils.OS;
/**
* The lombok GUI installer.
@@ -313,7 +313,7 @@ public class InstallerGUI {
final List<Pattern> exeNames = Installer.getIdeExecutableNames();
String file = null;
- if (IdeFinder.getOS() == OS.MAC_OS_X) {
+ if (OsUtils.getOS() == OS.MAC_OS_X) {
FileDialog chooser = new FileDialog(appWindow);
chooser.setMode(FileDialog.LOAD);
@@ -740,7 +740,7 @@ public class InstallerGUI {
} catch (Exception e) {
Runtime rt = Runtime.getRuntime();
try {
- switch (IdeFinder.getOS()) {
+ switch (OsUtils.getOS()) {
case WINDOWS:
String[] cmd = new String[4];
cmd[0] = "cmd.exe";
@@ -781,7 +781,7 @@ public class InstallerGUI {
*/
public void show() {
appWindow.setVisible(true);
- if (IdeFinder.getOS() == OS.MAC_OS_X) {
+ if (OsUtils.getOS() == OS.MAC_OS_X) {
try {
AppleNativeLook.go();
} catch (Throwable ignore) {
diff --git a/src/installer/lombok/installer/IdeFinder.java b/src/installer/lombok/installer/OsUtils.java
index f68a0e4c..2da7de09 100644
--- a/src/installer/lombok/installer/IdeFinder.java
+++ b/src/installer/lombok/installer/OsUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2011 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -34,9 +34,13 @@ import lombok.core.Version;
/**
* Implement and provide this class to add auto-finding a certain brand of IDEs to the lombok installer.
*/
-public abstract class IdeFinder {
+public final class OsUtils {
private static final AtomicBoolean windowsDriveInfoLibLoaded = new AtomicBoolean(false);
+ private OsUtils() {
+ // Prevent instantiation
+ }
+
private static void loadWindowsDriveInfoLib() throws IOException {
if (!windowsDriveInfoLibLoaded.compareAndSet(false, true)) return;
@@ -63,7 +67,7 @@ public abstract class IdeFinder {
}
private static boolean unpackDLL(String dllName, File target) throws IOException {
- InputStream in = IdeFinder.class.getResourceAsStream(dllName);
+ InputStream in = OsUtils.class.getResourceAsStream(dllName);
try {
try {
FileOutputStream out = new FileOutputStream(target);
@@ -130,15 +134,4 @@ public abstract class IdeFinder {
return OS.UNIX;
}
-
- /**
- * Look for installations of your IDE in the usual places.
- *
- * @param locations Add to this list any valid locations that you found.
- * @param problems
- * Add to this list any locations that look like installations,
- * but have problems that prevent you from installing/uninstalling from them. DONT add to this list
- * any common locations that have no installation at all - only add near misses.
- */
- public abstract void findIdes(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems);
}
diff --git a/src/installer/lombok/installer/eclipse/EclipseLocationProvider.java b/src/installer/lombok/installer/eclipse/EclipseLocationProvider.java
index 29716a1f..fa2ce958 100644
--- a/src/installer/lombok/installer/eclipse/EclipseLocationProvider.java
+++ b/src/installer/lombok/installer/eclipse/EclipseLocationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2011 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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,145 +21,24 @@
*/
package lombok.installer.eclipse;
-import static lombok.installer.IdeLocation.canonical;
+import java.util.Collections;
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import lombok.installer.IdeLocation;
import lombok.installer.IdeLocationProvider;
-import lombok.installer.CorruptedIdeLocationException;
-import lombok.installer.IdeFinder.OS;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(IdeLocationProvider.class)
-public class EclipseLocationProvider implements IdeLocationProvider {
- @Override public IdeLocation create(String path) throws CorruptedIdeLocationException {
- return create0(path);
- }
-
- protected List<String> getEclipseExecutableNames() {
- return Arrays.asList("eclipse.app", "eclipse.exe", "eclipse");
- }
-
- protected String getIniName() {
- return "eclipse.ini";
- }
-
- protected IdeLocation makeLocation(String name, File ini) throws CorruptedIdeLocationException {
- return new EclipseLocation(name, ini);
- }
-
- protected String getMacAppName() {
- return "Eclipse.app";
- }
-
- protected String getUnixAppName() {
- return "eclipse";
- }
-
- /**
- * Create a new EclipseLocation by pointing at either the directory contains the Eclipse executable, or the executable itself,
- * or an eclipse.ini file.
- *
- * @throws NotAnIdeLocationException
- * If this isn't an Eclipse executable or a directory with an
- * Eclipse executable.
- */
- protected IdeLocation create0(String path) throws CorruptedIdeLocationException {
- if (path == null) throw new NullPointerException("path");
- File p = new File(path);
-
- if (!p.exists()) return null;
- if (p.isDirectory()) {
- for (String possibleExeName : getEclipseExecutableNames()) {
- File f = new File(p, possibleExeName);
- if (f.exists()) return findEclipseIniFromExe(f, 0);
- }
-
- File f = new File(p, getIniName());
- if (f.exists()) return new EclipseLocation(canonical(p), f);
- }
-
- if (p.isFile()) {
- if (p.getName().equalsIgnoreCase(getIniName())) {
- return new EclipseLocation(canonical(p.getParentFile()), p);
- }
- }
-
- if (getEclipseExecutableNames().contains(p.getName().toLowerCase())) {
- return findEclipseIniFromExe(p, 0);
- }
-
- return null;
- }
-
- private IdeLocation findEclipseIniFromExe(File exePath, int loopCounter) throws CorruptedIdeLocationException {
- /* Try looking for eclipse.ini as sibling to the executable */ {
- File ini = new File(exePath.getParentFile(), getIniName());
- if (ini.isFile()) return makeLocation(canonical(exePath), ini);
- }
-
- /* Try looking for Eclipse.app/Contents/MacOS/eclipse.ini as sibling to executable; this works on Mac OS X. */ {
- File ini = new File(exePath.getParentFile(), getMacAppName() + "/Contents/MacOS/" + getIniName());
- if (ini.isFile()) return makeLocation(canonical(exePath), ini);
- }
-
- /* Starting with Eclipse Mars (with the oomph installer), the structure has changed, and it's now at Eclipse.app/Contents/Eclipse/eclipse.ini*/ {
- File ini = new File(exePath.getParentFile(), getMacAppName() + "/Contents/Eclipse/" + getIniName());
- if (ini.isFile()) return makeLocation(canonical(exePath), ini);
- }
-
- /* If executable is a soft link, follow it and retry. */ {
- if (loopCounter < 50) {
- try {
- String oPath = exePath.getAbsolutePath();
- String nPath = exePath.getCanonicalPath();
- if (!oPath.equals(nPath)) try {
- IdeLocation loc = findEclipseIniFromExe(new File(nPath), loopCounter + 1);
- if (loc != null) return loc;
- } catch (CorruptedIdeLocationException ignore) {
- // Unlinking didn't help find an eclipse, so continue.
- }
- } catch (IOException ignore) { /* okay, that didn't work, assume it isn't a soft link then. */ }
- }
- }
-
- /* If executable is a linux LSB-style path, then look in the usual places that package managers like apt-get use.*/ {
- String path = exePath.getAbsolutePath();
- try {
- path = exePath.getCanonicalPath();
- } catch (IOException ignore) { /* We'll stick with getAbsolutePath()'s result then. */ }
-
- if (path.equals("/usr/bin/" + getUnixAppName()) || path.equals("/bin/" + getUnixAppName()) || path.equals("/usr/local/bin/" + getUnixAppName())) {
- File ini = new File("/usr/lib/" + getUnixAppName() + "/" + getIniName());
- if (ini.isFile()) return makeLocation(path, ini);
- ini = new File("/usr/local/lib/" + getUnixAppName() + "/" + getIniName());
- if (ini.isFile()) return makeLocation(path, ini);
- ini = new File("/usr/local/etc/" + getUnixAppName() + "/" + getIniName());
- if (ini.isFile()) return makeLocation(path, ini);
- ini = new File("/etc/" + getIniName());
- if (ini.isFile()) return makeLocation(path, ini);
- }
- }
-
- /* If we get this far, we lose. */
- return null;
- }
-
- @Override public Pattern getLocationSelectors(OS os) {
- switch (os) {
- case MAC_OS_X:
- return Pattern.compile("^(eclipse|eclipse\\.ini|eclipse\\.app)$", Pattern.CASE_INSENSITIVE);
- case WINDOWS:
- return Pattern.compile("^(eclipse\\.exe|eclipse\\.ini)$", Pattern.CASE_INSENSITIVE);
- default:
- case UNIX:
- return Pattern.compile("^(eclipse|eclipse\\.ini)$", Pattern.CASE_INSENSITIVE);
- }
+public class EclipseLocationProvider extends EclipseProductLocationProvider {
+
+ private static final EclipseProductDescriptor ECLIPSE = new StandardProductDescriptor(
+ "Eclipse",
+ "eclipse",
+ "eclipse",
+ EclipseLocationProvider.class.getResource("eclipse.png"),
+ Collections.<String>emptySet()
+ );
+
+ public EclipseLocationProvider() {
+ super(ECLIPSE);
}
}
diff --git a/src/installer/lombok/installer/eclipse/STSLocation.java b/src/installer/lombok/installer/eclipse/EclipseProductDescriptor.java
index 40ade40a..8f736a57 100644
--- a/src/installer/lombok/installer/eclipse/STSLocation.java
+++ b/src/installer/lombok/installer/eclipse/EclipseProductDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Project Lombok Authors.
+ * Copyright (C) 2016 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,25 +21,21 @@
*/
package lombok.installer.eclipse;
-import java.io.File;
import java.net.URL;
+import java.util.List;
+import java.util.regex.Pattern;
-import lombok.installer.CorruptedIdeLocationException;
-
-public class STSLocation extends EclipseLocation {
- public STSLocation(String nameOfLocation, File pathToEclipseIni) throws CorruptedIdeLocationException {
- super(nameOfLocation, pathToEclipseIni);
- }
-
- @Override public URL getIdeIcon() {
- return STSLocation.class.getResource("STS.png");
- }
-
- @Override protected String getIniFileName() {
- return "STS.ini";
- }
-
- @Override protected String getTypeName() {
- return "STS";
- }
-}
+public interface EclipseProductDescriptor {
+ String getProductName();
+ String getWindowsExecutableName();
+ String getUnixAppName();
+ String getMacAppName();
+ String getDirectoryName();
+ List<String> getExecutableNames();
+ List<String> getSourceDirsOnWindows();
+ List<String> getSourceDirsOnMac();
+ List<String> getSourceDirsOnUnix();
+ String getIniFileName();
+ Pattern getLocationSelectors();
+ URL getIdeIcon();
+} \ No newline at end of file
diff --git a/src/installer/lombok/installer/eclipse/EclipseLocation.java b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
index 6c63c48d..886e3e85 100644
--- a/src/installer/lombok/installer/eclipse/EclipseLocation.java
+++ b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -35,7 +35,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.installer.CorruptedIdeLocationException;
-import lombok.installer.IdeFinder;
+import lombok.installer.OsUtils;
import lombok.installer.IdeLocation;
import lombok.installer.InstallException;
import lombok.installer.Installer;
@@ -46,23 +46,18 @@ import lombok.installer.UninstallException;
* An instance can figure out if an Eclipse installation has been lombok-ified, and can
* install and uninstall lombok from the Eclipse installation.
*/
-public class EclipseLocation extends IdeLocation {
+public final class EclipseProductLocation extends IdeLocation {
+
+ private static final String OS_NEWLINE = OsUtils.getOS().getLineEnding();
+
+ private final EclipseProductDescriptor descriptor;
private final String name;
private final File eclipseIniPath;
private final String pathToLombokJarPrefix;
- private volatile boolean hasLombok;
-
- private static final String OS_NEWLINE = IdeFinder.getOS().getLineEnding();
-
- protected String getTypeName() {
- return "eclipse";
- }
-
- protected String getIniFileName() {
- return "eclipse.ini";
- }
+ private final boolean hasLombok;
- EclipseLocation(String nameOfLocation, File pathToEclipseIni) throws CorruptedIdeLocationException {
+ EclipseProductLocation(EclipseProductDescriptor descriptor, String nameOfLocation, File pathToEclipseIni) throws CorruptedIdeLocationException {
+ this.descriptor = descriptor;
this.name = nameOfLocation;
this.eclipseIniPath = pathToEclipseIni;
File p1 = pathToEclipseIni.getParentFile();
@@ -78,8 +73,8 @@ public class EclipseLocation extends IdeLocation {
this.hasLombok = checkForLombok(eclipseIniPath);
} catch (IOException e) {
throw new CorruptedIdeLocationException(
- "I can't read the configuration file of the " + getTypeName() + " installed at " + name + "\n" +
- "You may need to run this installer with root privileges if you want to modify that " + getTypeName() + ".", getTypeName(), e);
+ "I can't read the configuration file of the " + descriptor.getProductName() + " installed at " + name + "\n" +
+ "You may need to run this installer with root privileges if you want to modify that " + descriptor.getProductName() + ".", descriptor.getProductName(), e);
}
}
@@ -88,8 +83,8 @@ public class EclipseLocation extends IdeLocation {
}
@Override public boolean equals(Object o) {
- if (!(o instanceof EclipseLocation)) return false;
- return ((EclipseLocation)o).eclipseIniPath.equals(eclipseIniPath);
+ if (!(o instanceof EclipseProductLocation)) return false;
+ return ((EclipseProductLocation)o).eclipseIniPath.equals(eclipseIniPath);
}
/**
@@ -108,13 +103,13 @@ public class EclipseLocation extends IdeLocation {
return hasLombok;
}
- private final Pattern JAVA_AGENT_LINE_MATCHER = Pattern.compile(
+ private static final Pattern JAVA_AGENT_LINE_MATCHER = Pattern.compile(
"^\\-javaagent\\:.*lombok.*\\.jar$", Pattern.CASE_INSENSITIVE);
- private final Pattern BOOTCLASSPATH_LINE_MATCHER = Pattern.compile(
+ private static final Pattern BOOTCLASSPATH_LINE_MATCHER = Pattern.compile(
"^\\-Xbootclasspath\\/a\\:(.*lombok.*\\.jar.*)$", Pattern.CASE_INSENSITIVE);
- private boolean checkForLombok(File iniFile) throws IOException {
+ private static boolean checkForLombok(File iniFile) throws IOException {
if (!iniFile.exists()) return false;
FileInputStream fis = new FileInputStream(iniFile);
try {
@@ -206,7 +201,7 @@ public class EclipseLocation extends IdeLocation {
File lombokJar = new File(dir, "lombok.jar");
if (lombokJar.exists()) {
if (!lombokJar.delete()) {
- if (IdeFinder.getOS() == IdeFinder.OS.WINDOWS && Installer.isSelf(lombokJar.getAbsolutePath())) {
+ if (OsUtils.getOS() == OsUtils.OS.WINDOWS && Installer.isSelf(lombokJar.getAbsolutePath())) {
lombokJarsForWhichCantDeleteSelf.add(lombokJar);
} else {
throw new UninstallException(
@@ -228,14 +223,14 @@ public class EclipseLocation extends IdeLocation {
throw new UninstallException(true, String.format(
"lombok.jar cannot delete itself on windows.\nHowever, lombok has been uncoupled from your %s.\n" +
"You can safely delete this jar file. You can find it at:\n%s",
- getTypeName(), lombokJarsForWhichCantDeleteSelf.get(0).getAbsolutePath()), null);
+ descriptor.getProductName(), lombokJarsForWhichCantDeleteSelf.get(0).getAbsolutePath()), null);
}
}
private static String generateWriteErrorMessage() {
String osSpecificError;
- switch (IdeFinder.getOS()) {
+ switch (OsUtils.getOS()) {
default:
case MAC_OS_X:
case UNIX:
@@ -265,7 +260,7 @@ public class EclipseLocation extends IdeLocation {
// If someone knows how to fix this, please do so, as this current hack solution (putting the absolute path
// to the jar files in your eclipse.ini) means you can't move your eclipse around on linux without lombok
// breaking it. NB: rerunning lombok.jar installer and hitting 'update' will fix it if you do that.
- boolean fullPathRequired = IdeFinder.getOS() == EclipseFinder.OS.UNIX || System.getProperty("lombok.installer.fullpath") != null;
+ boolean fullPathRequired = OsUtils.getOS() == OsUtils.OS.UNIX || System.getProperty("lombok.installer.fullpath") != null;
boolean installSucceeded = false;
StringBuilder newContents = new StringBuilder();
@@ -303,7 +298,7 @@ public class EclipseLocation extends IdeLocation {
"I can't read my own jar file. I think you've found a bug in this installer!\nI suggest you restart it " +
"and use the 'what do I do' link, to manually install lombok. Also, tell us about this at:\n" +
"http://groups.google.com/group/project-lombok - Thanks!", e);
- throw new InstallException("I can't write to your " + getTypeName() + " directory at " + name + generateWriteErrorMessage(), e);
+ throw new InstallException("I can't write to your " + descriptor.getProductName() + " directory at " + name + generateWriteErrorMessage(), e);
}
}
@@ -369,14 +364,14 @@ public class EclipseLocation extends IdeLocation {
}
if (!installSucceeded) {
- throw new InstallException("I can't find the " + getIniFileName() + " file. Is this a real " + getTypeName() + " installation?", null);
+ throw new InstallException("I can't find the " + descriptor.getIniFileName() + " file. Is this a real " + descriptor.getProductName() + " installation?", null);
}
- return "If you start " + getTypeName() + " with a custom -vm parameter, you'll need to add:<br>" +
+ return "If you start " + descriptor.getProductName() + " with a custom -vm parameter, you'll need to add:<br>" +
"<code>-vmargs -javaagent:lombok.jar</code><br>as parameter as well.";
}
@Override public URL getIdeIcon() {
- return EclipseLocation.class.getResource("eclipse.png");
+ return descriptor.getIdeIcon();
}
}
diff --git a/src/installer/lombok/installer/eclipse/EclipseFinder.java b/src/installer/lombok/installer/eclipse/EclipseProductLocationProvider.java
index 8a1a689a..3710d7d9 100644
--- a/src/installer/lombok/installer/eclipse/EclipseFinder.java
+++ b/src/installer/lombok/installer/eclipse/EclipseProductLocationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2011 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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
@@ -22,109 +22,130 @@
package lombok.installer.eclipse;
import static java.util.Arrays.asList;
+import static lombok.installer.IdeLocation.canonical;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.regex.Pattern;
-import lombok.installer.IdeFinder;
-import lombok.installer.IdeLocation;
import lombok.installer.CorruptedIdeLocationException;
+import lombok.installer.OsUtils;
+import lombok.installer.IdeLocation;
+import lombok.installer.IdeLocationProvider;
-import org.mangosdk.spi.ProviderFor;
+public class EclipseProductLocationProvider implements IdeLocationProvider {
+ private final EclipseProductDescriptor descriptor;
-@ProviderFor(IdeFinder.class)
-public class EclipseFinder extends IdeFinder {
- /** should be lowercase! */
- protected String getDirName() {
- return "eclipse";
- }
-
- protected String getWindowsExecutableName() {
- return "eclipse.exe";
- }
-
- protected String getUnixExecutableName() {
- return "eclipse";
- }
-
- protected String getMacExecutableName() {
- return "Eclipse.app";
+ EclipseProductLocationProvider(EclipseProductDescriptor descriptor) {
+ this.descriptor = descriptor;
}
- protected IdeLocation createLocation(String guess) throws CorruptedIdeLocationException {
- return new EclipseLocationProvider().create0(guess);
- }
-
- protected List<String> getSourceDirsOnWindows() {
- return Arrays.asList("\\", "\\Program Files", "\\Program Files (x86)", System.getProperty("user.home", "."));
+ @Override public final IdeLocation create(String path) throws CorruptedIdeLocationException {
+ return create0(path);
}
/**
- * Returns a list of paths of Eclipse installations.
+ * Create a new EclipseLocation by pointing at either the directory contains the Eclipse executable, or the executable itself,
+ * or an eclipse.ini file.
*
- * The search process works by scanning for each 'source dir' for either an eclipse installation or a folder containing the text returned
- * by getDirName(). If such a folder is found, this process is applied recursively. On windows, this process is run on each drive letter
- * which represents a physical hard disk. If the native windows API call to determine these drive letters fails, only 'C:' is checked.
+ * @throws NotAnIdeLocationException
+ * If this isn't an Eclipse executable or a directory with an
+ * Eclipse executable.
*/
- private List<String> getSourceDirsOnWindowsWithDriveLetters() {
- List<String> driveLetters = asList("C");
- try {
- driveLetters = getDrivesOnWindows();
- } catch (Throwable ignore) {
- ignore.printStackTrace();
+ private IdeLocation create0(String path) throws CorruptedIdeLocationException {
+ if (path == null) throw new NullPointerException("path");
+ String iniName = descriptor.getIniFileName();
+ File p = new File(path);
+
+ if (!p.exists()) return null;
+ if (p.isDirectory()) {
+ for (String possibleExeName : descriptor.getExecutableNames()) {
+ File f = new File(p, possibleExeName);
+ if (f.exists()) return findEclipseIniFromExe(f, 0);
+ }
+
+ File f = new File(p, iniName);
+ if (f.exists()) return makeLocation(canonical(p), f);
}
- List<String> sourceDirs = new ArrayList<String>();
- for (String letter : driveLetters) {
- for (String possibleSource : getSourceDirsOnWindows()) {
- if (!isDriveSpecificOnWindows(possibleSource)) {
- sourceDirs.add(letter + ":" + possibleSource);
- }
+
+ if (p.isFile()) {
+ if (p.getName().equalsIgnoreCase(iniName)) {
+ return makeLocation(canonical(p.getParentFile()), p);
}
}
- for (String possibleSource : getSourceDirsOnWindows()) {
- if (isDriveSpecificOnWindows(possibleSource)) sourceDirs.add(possibleSource);
+
+ if (descriptor.getExecutableNames().contains(p.getName().toLowerCase())) {
+ return findEclipseIniFromExe(p, 0);
}
- return sourceDirs;
+ return null;
}
- public boolean isDriveSpecificOnWindows(String path) {
- return path.length() > 1 && path.charAt(1) == ':';
- }
-
- protected List<String> getSourceDirsOnMac() {
- return Arrays.asList("/Applications", System.getProperty("user.home", "."));
- }
-
- protected List<String> getSourceDirsOnUnix() {
- return Arrays.asList(System.getProperty("user.home", "."));
- }
-
- private List<File> transformToFiles(List<String> fileNames) {
- List<File> files = new ArrayList<File>();
- for (String fileName : fileNames) {
- files.add(new File(fileName));
+ private IdeLocation findEclipseIniFromExe(File exePath, int loopCounter) throws CorruptedIdeLocationException {
+ String iniName = descriptor.getIniFileName();
+ /* Try looking for eclipse.ini as sibling to the executable */ {
+ File ini = new File(exePath.getParentFile(), iniName);
+ if (ini.isFile()) return makeLocation(canonical(exePath), ini);
}
- return files;
+
+ String macAppName = descriptor.getMacAppName();
+ /* Try looking for Eclipse.app/Contents/MacOS/eclipse.ini as sibling to executable; this works on Mac OS X. */ {
+ File ini = new File(exePath.getParentFile(), macAppName + "/Contents/MacOS/" + iniName);
+ if (ini.isFile()) return makeLocation(canonical(exePath), ini);
+ }
+
+ /* Starting with Eclipse Mars (with the oomph installer), the structure has changed, and it's now at Eclipse.app/Contents/Eclipse/eclipse.ini*/ {
+ File ini = new File(exePath.getParentFile(), macAppName + "/Contents/Eclipse/" + iniName);
+ if (ini.isFile()) return makeLocation(canonical(exePath), ini);
+ }
+
+ /* If executable is a soft link, follow it and retry. */ {
+ if (loopCounter < 50) {
+ try {
+ String oPath = exePath.getAbsolutePath();
+ String nPath = exePath.getCanonicalPath();
+ if (!oPath.equals(nPath)) try {
+ IdeLocation loc = findEclipseIniFromExe(new File(nPath), loopCounter + 1);
+ if (loc != null) return loc;
+ } catch (CorruptedIdeLocationException ignore) {
+ // Unlinking didn't help find an eclipse, so continue.
+ }
+ } catch (IOException ignore) { /* okay, that didn't work, assume it isn't a soft link then. */ }
+ }
+ }
+
+ /* If executable is a linux LSB-style path, then look in the usual places that package managers like apt-get use.*/ {
+ String path = exePath.getAbsolutePath();
+ try {
+ path = exePath.getCanonicalPath();
+ } catch (IOException ignore) { /* We'll stick with getAbsolutePath()'s result then. */ }
+
+ String unixAppName = descriptor.getUnixAppName();
+ if (path.equals("/usr/bin/" + unixAppName) || path.equals("/bin/" + unixAppName) || path.equals("/usr/local/bin/" + unixAppName)) {
+ File ini = new File("/usr/lib/" + unixAppName + "/" + iniName);
+ if (ini.isFile()) return makeLocation(path, ini);
+ ini = new File("/usr/local/lib/" + unixAppName + "/" + iniName);
+ if (ini.isFile()) return makeLocation(path, ini);
+ ini = new File("/usr/local/etc/" + unixAppName + "/" + iniName);
+ if (ini.isFile()) return makeLocation(path, ini);
+ ini = new File("/etc/" + iniName);
+ if (ini.isFile()) return makeLocation(path, ini);
+ }
+ }
+
+ /* If we get this far, we lose. */
+ return null;
}
- private List<File> getFlatSourceLocationsOnUnix() {
- List<File> dirs = new ArrayList<File>();
- dirs.add(new File("/usr/bin/"));
- dirs.add(new File("/usr/local/bin/"));
- dirs.add(new File(System.getProperty("user.home", "."), "bin/"));
- return dirs;
+ private IdeLocation makeLocation(String name, File ini) throws CorruptedIdeLocationException {
+ return new EclipseProductLocation(descriptor, name, ini);
}
- private List<File> getNestedSourceLocationOnUnix() {
- List<File> dirs = new ArrayList<File>();
- dirs.add(new File("/usr/local/share"));
- dirs.add(new File("/usr/local"));
- dirs.add(new File("/usr/share"));
- return dirs;
+ @Override public Pattern getLocationSelectors() {
+ return descriptor.getLocationSelectors();
}
/**
@@ -141,7 +162,7 @@ public class EclipseFinder extends IdeFinder {
*/
@Override
public void findIdes(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
- switch (getOS()) {
+ switch (OsUtils.getOS()) {
case WINDOWS:
new WindowsFinder().findEclipse(locations, problems);
break;
@@ -155,17 +176,74 @@ public class EclipseFinder extends IdeFinder {
}
}
+ private List<File> transformToFiles(List<String> fileNames) {
+ List<File> files = new ArrayList<File>();
+ for (String fileName : fileNames) {
+ files.add(new File(fileName));
+ }
+ return files;
+ }
+
+ private List<File> getFlatSourceLocationsOnUnix() {
+ List<File> dirs = new ArrayList<File>();
+ dirs.add(new File("/usr/bin/"));
+ dirs.add(new File("/usr/local/bin/"));
+ dirs.add(new File(System.getProperty("user.home", "."), "bin/"));
+ return dirs;
+ }
+
+ private List<File> getNestedSourceLocationOnUnix() {
+ List<File> dirs = new ArrayList<File>();
+ dirs.add(new File("/usr/local/share"));
+ dirs.add(new File("/usr/local"));
+ dirs.add(new File("/usr/share"));
+ return dirs;
+ }
+
private class UnixFinder extends DirectoryFinder {
UnixFinder() {
super(getNestedSourceLocationOnUnix(), getFlatSourceLocationsOnUnix());
}
@Override protected String findEclipseOnPlatform(File dir) {
- File possible = new File(dir, getUnixExecutableName());
+ File possible = new File(dir, descriptor.getUnixAppName());
return (possible.exists()) ? possible.getAbsolutePath() : null;
}
}
+ /**
+ * Returns a list of paths of Eclipse installations.
+ *
+ * The search process works by scanning for each 'source dir' for either an eclipse installation or a folder containing the text returned
+ * by getDirName(). If such a folder is found, this process is applied recursively. On windows, this process is run on each drive letter
+ * which represents a physical hard disk. If the native windows API call to determine these drive letters fails, only 'C:' is checked.
+ */
+ private List<String> getSourceDirsOnWindowsWithDriveLetters() {
+ List<String> driveLetters = asList("C");
+ try {
+ driveLetters = OsUtils.getDrivesOnWindows();
+ } catch (Throwable ignore) {
+ ignore.printStackTrace();
+ }
+ List<String> sourceDirs = new ArrayList<String>();
+ for (String letter : driveLetters) {
+ for (String possibleSource : descriptor.getSourceDirsOnWindows()) {
+ if (!isDriveSpecificOnWindows(possibleSource)) {
+ sourceDirs.add(letter + ":" + possibleSource);
+ }
+ }
+ }
+ for (String possibleSource : descriptor.getSourceDirsOnWindows()) {
+ if (isDriveSpecificOnWindows(possibleSource)) sourceDirs.add(possibleSource);
+ }
+
+ return sourceDirs;
+ }
+
+ private boolean isDriveSpecificOnWindows(String path) {
+ return path.length() > 1 && path.charAt(1) == ':';
+ }
+
private class WindowsFinder extends DirectoryFinder {
WindowsFinder() {
super(transformToFiles(getSourceDirsOnWindowsWithDriveLetters()), Collections.<File>emptyList());
@@ -174,20 +252,20 @@ public class EclipseFinder extends IdeFinder {
/** Checks if the provided directory contains 'eclipse.exe', and if so, returns the directory, otherwise null. */
@Override
protected String findEclipseOnPlatform(File dir) {
- File possible = new File(dir, getWindowsExecutableName());
+ File possible = new File(dir, descriptor.getWindowsExecutableName());
return (possible.isFile()) ? dir.getAbsolutePath() : null;
}
}
private class MacFinder extends DirectoryFinder {
MacFinder() {
- super(transformToFiles(getSourceDirsOnMac()), Collections.<File>emptyList());
+ super(transformToFiles(descriptor.getSourceDirsOnMac()), Collections.<File>emptyList());
}
protected String findEclipseOnPlatform(File dir) {
- if (dir.getName().toLowerCase().equals(getMacExecutableName().toLowerCase())) return dir.getParent();
- if (dir.getName().toLowerCase().contains(getDirName())) {
- if (new File(dir, getMacExecutableName()).exists()) return dir.toString();
+ if (dir.getName().toLowerCase().equals(descriptor.getMacAppName().toLowerCase())) return dir.getParent();
+ if (dir.getName().toLowerCase().contains(descriptor.getDirectoryName())) {
+ if (new File(dir, descriptor.getMacAppName()).exists()) return dir.toString();
}
return null;
}
@@ -202,14 +280,14 @@ public class EclipseFinder extends IdeFinder {
this.flatSourceDirs = flatSourceDirs;
}
- public void findEclipse(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
+ void findEclipse(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
for (File dir : nestedSourceDirs) recurseDirectory(locations, problems, dir);
for (File dir : flatSourceDirs) findEclipse(locations, problems, dir);
}
- protected abstract String findEclipseOnPlatform(File dir);
+ abstract String findEclipseOnPlatform(File dir);
- protected void recurseDirectory(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems, File dir) {
+ void recurseDirectory(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems, File dir) {
recurseDirectory0(locations, problems, dir, 0);
}
@@ -223,19 +301,19 @@ public class EclipseFinder extends IdeFinder {
for (File dir : listFiles) {
if (!dir.isDirectory()) continue;
try {
- if (dir.getName().toLowerCase().contains(getDirName())) {
+ if (dir.getName().toLowerCase().contains(descriptor.getDirectoryName())) {
findEclipse(locations, problems, dir);
if (loopCounter < 50) recurseDirectory0(locations, problems, dir, loopCounter + 1);
}
} catch (Exception ignore) {}
}
}
-
+
private void findEclipse(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems, File dir) {
String eclipseLocation = findEclipseOnPlatform(dir);
if (eclipseLocation != null) {
try {
- IdeLocation newLocation = createLocation(eclipseLocation);
+ IdeLocation newLocation = create(eclipseLocation);
if (newLocation != null) locations.add(newLocation);
} catch (CorruptedIdeLocationException e) {
problems.add(e);
diff --git a/src/installer/lombok/installer/eclipse/JbdsFinder.java b/src/installer/lombok/installer/eclipse/JbdsFinder.java
deleted file mode 100644
index 2dfaacba..00000000
--- a/src/installer/lombok/installer/eclipse/JbdsFinder.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2013 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.installer.eclipse;
-
-import java.util.Arrays;
-import java.util.List;
-
-import lombok.installer.CorruptedIdeLocationException;
-import lombok.installer.IdeFinder;
-import lombok.installer.IdeLocation;
-
-import org.mangosdk.spi.ProviderFor;
-
-/**
- * JBDS (JBoss Developer Studio) is an eclipse variant.
- * Other than different executable names, it's the same as eclipse, as far as lombok support goes.
- */
-@ProviderFor(IdeFinder.class)
-public class JbdsFinder extends EclipseFinder {
- @Override protected IdeLocation createLocation(String guess) throws CorruptedIdeLocationException {
- return new JbdsLocationProvider().create0(guess);
- }
-
- @Override protected String getDirName() {
- return "studio";
- }
-
- @Override protected String getMacExecutableName() {
- return "jbdevstudio.app";
- }
-
- @Override protected String getUnixExecutableName() {
- return "jbdevstudio";
- }
-
- @Override protected String getWindowsExecutableName() {
- return "jbdevstudio.exe";
- }
-
- @Override protected List<String> getSourceDirsOnWindows() {
- return Arrays.asList("\\", "\\Program Files", "\\Program Files (x86)", System.getProperty("user.home", "."));
- }
-
- @Override protected List<String> getSourceDirsOnMac() {
- return Arrays.asList("/Applications", System.getProperty("user.home", "."));
- }
-
- @Override protected List<String> getSourceDirsOnUnix() {
- return Arrays.asList(System.getProperty("user.home", "."));
- }
-}
diff --git a/src/installer/lombok/installer/eclipse/JbdsLocationProvider.java b/src/installer/lombok/installer/eclipse/JbdsLocationProvider.java
index e6df0e43..635f304a 100644
--- a/src/installer/lombok/installer/eclipse/JbdsLocationProvider.java
+++ b/src/installer/lombok/installer/eclipse/JbdsLocationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Project Lombok Authors.
+ * Copyright (C) 2013-2016 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,49 +21,24 @@
*/
package lombok.installer.eclipse;
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Pattern;
+import java.util.Collections;
-import lombok.installer.CorruptedIdeLocationException;
-import lombok.installer.IdeLocation;
import lombok.installer.IdeLocationProvider;
-import lombok.installer.IdeFinder.OS;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(IdeLocationProvider.class)
-public class JbdsLocationProvider extends EclipseLocationProvider {
- @Override protected List<String> getEclipseExecutableNames() {
- return Arrays.asList("jbdevstudio.app", "jbdevstudio.exe", "jbdevstudioc.exe", "jbdevstudio");
- }
-
- @Override protected String getIniName() {
- return "jbdevstudio.ini";
- }
-
- @Override protected IdeLocation makeLocation(String name, File ini) throws CorruptedIdeLocationException {
- return new JbdsLocation(name, ini);
- }
-
- @Override protected String getMacAppName() {
- return "jbdevstudio.app";
- }
+public class JbdsLocationProvider extends EclipseProductLocationProvider {
- @Override protected String getUnixAppName() {
- return "jbdevstudio";
- }
+ private static final EclipseProductDescriptor JBDS = new StandardProductDescriptor(
+ "JBoss Developer Studio",
+ "jbdevstudio",
+ "studio",
+ JbdsLocationProvider.class.getResource("jbds.png"),
+ Collections.<String>emptySet()
+ );
- @Override public Pattern getLocationSelectors(OS os) {
- switch (os) {
- case MAC_OS_X:
- return Pattern.compile("^(jbdevstudio|jbdevstudio\\.ini|jbdevstudio\\.app)$", Pattern.CASE_INSENSITIVE);
- case WINDOWS:
- return Pattern.compile("^(jbdevstudioc?\\.exe|jbdevstudio\\.ini)$", Pattern.CASE_INSENSITIVE);
- default:
- case UNIX:
- return Pattern.compile("^(jbdevstudio|jbdevstudio\\.ini)$", Pattern.CASE_INSENSITIVE);
- }
+ public JbdsLocationProvider() {
+ super(JBDS);
}
}
diff --git a/src/installer/lombok/installer/eclipse/JbdsLocation.java b/src/installer/lombok/installer/eclipse/MyEclipseLocationProvider.java
index 81fb5261..298cabd6 100644
--- a/src/installer/lombok/installer/eclipse/JbdsLocation.java
+++ b/src/installer/lombok/installer/eclipse/MyEclipseLocationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Project Lombok Authors.
+ * Copyright (C) 2016 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,25 +21,24 @@
*/
package lombok.installer.eclipse;
-import java.io.File;
-import java.net.URL;
+import java.util.Collections;
-import lombok.installer.CorruptedIdeLocationException;
+import lombok.installer.IdeLocationProvider;
-public class JbdsLocation extends EclipseLocation {
- public JbdsLocation(String nameOfLocation, File pathToEclipseIni) throws CorruptedIdeLocationException {
- super(nameOfLocation, pathToEclipseIni);
- }
-
- @Override public URL getIdeIcon() {
- return JbdsLocation.class.getResource("jbds.png");
- }
+import org.mangosdk.spi.ProviderFor;
+
+@ProviderFor(IdeLocationProvider.class)
+public class MyEclipseLocationProvider extends EclipseProductLocationProvider {
- @Override protected String getIniFileName() {
- return "jbdevstudio.ini";
- }
+ private static final EclipseProductDescriptor MY_ECLIPSE = new StandardProductDescriptor(
+ "MyEclipse",
+ "myeclipse",
+ "myeclipse",
+ MyEclipseLocationProvider.class.getResource("myeclipse.png"),
+ Collections.<String>emptySet()
+ );
- @Override protected String getTypeName() {
- return "JBoss Developer Studio";
+ public MyEclipseLocationProvider() {
+ super(MY_ECLIPSE);
}
}
diff --git a/src/installer/lombok/installer/eclipse/RhdsLocationProvider.java b/src/installer/lombok/installer/eclipse/RhdsLocationProvider.java
new file mode 100644
index 00000000..5e1d303d
--- /dev/null
+++ b/src/installer/lombok/installer/eclipse/RhdsLocationProvider.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013-2016 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.installer.eclipse;
+
+import java.util.Collections;
+
+import lombok.installer.IdeLocationProvider;
+
+import org.mangosdk.spi.ProviderFor;
+
+@ProviderFor(IdeLocationProvider.class)
+public class RhdsLocationProvider extends EclipseProductLocationProvider {
+
+ private static final EclipseProductDescriptor RHDS = new StandardProductDescriptor(
+ "Red Hat JBoss Developer Studio",
+ "devstudio",
+ "studio",
+ RhdsLocationProvider.class.getResource("rhds.png"),
+ Collections.<String>emptySet()
+ );
+
+ public RhdsLocationProvider() {
+ super(RHDS);
+ }
+}
diff --git a/src/installer/lombok/installer/eclipse/STSFinder.java b/src/installer/lombok/installer/eclipse/STSFinder.java
deleted file mode 100644
index 82bc9b80..00000000
--- a/src/installer/lombok/installer/eclipse/STSFinder.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2009 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.installer.eclipse;
-
-import java.util.Arrays;
-import java.util.List;
-
-import lombok.installer.CorruptedIdeLocationException;
-import lombok.installer.IdeFinder;
-import lombok.installer.IdeLocation;
-
-import org.mangosdk.spi.ProviderFor;
-
-/**
- * STS (Springsource Tool Suite) is an eclipse variant.
- * Other than different executable names, it's the same as eclipse, as far as lombok support goes.
- */
-@ProviderFor(IdeFinder.class)
-public class STSFinder extends EclipseFinder {
- @Override protected IdeLocation createLocation(String guess) throws CorruptedIdeLocationException {
- return new STSLocationProvider().create0(guess);
- }
-
- @Override protected String getDirName() {
- return "sts";
- }
-
- @Override protected String getMacExecutableName() {
- return "STS.app";
- }
-
- @Override protected String getUnixExecutableName() {
- return "STS";
- }
-
- @Override protected String getWindowsExecutableName() {
- return "STS.exe";
- }
-
- @Override protected List<String> getSourceDirsOnWindows() {
- return Arrays.asList("\\", "\\springsource", "\\Program Files", "\\Program Files (x86)", "\\Program Files\\springsource", "\\Program Files (x86)\\springsource", System.getProperty("user.home", "."), System.getProperty("user.home", ".") + "\\springsource");
- }
-
- @Override protected List<String> getSourceDirsOnMac() {
- return Arrays.asList("/Applications", "/Applications/springsource", System.getProperty("user.home", "."), System.getProperty("user.home", ".") + "/springsource");
- }
-
- @Override protected List<String> getSourceDirsOnUnix() {
- return Arrays.asList(System.getProperty("user.home", "."), System.getProperty("user.home", ".") + "/springsource");
- }
-}
diff --git a/src/installer/lombok/installer/eclipse/STSLocationProvider.java b/src/installer/lombok/installer/eclipse/STSLocationProvider.java
index 7d129838..d2efb956 100644
--- a/src/installer/lombok/installer/eclipse/STSLocationProvider.java
+++ b/src/installer/lombok/installer/eclipse/STSLocationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Project Lombok Authors.
+ * Copyright (C) 2009-2016 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,49 +21,23 @@
*/
package lombok.installer.eclipse;
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Pattern;
+import java.util.Collections;
-import lombok.installer.CorruptedIdeLocationException;
-import lombok.installer.IdeLocation;
import lombok.installer.IdeLocationProvider;
-import lombok.installer.IdeFinder.OS;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(IdeLocationProvider.class)
-public class STSLocationProvider extends EclipseLocationProvider {
- @Override protected List<String> getEclipseExecutableNames() {
- return Arrays.asList("sts.app", "sts.exe", "stsc.exe", "sts");
- }
-
- @Override protected String getIniName() {
- return "STS.ini";
- }
-
- @Override protected IdeLocation makeLocation(String name, File ini) throws CorruptedIdeLocationException {
- return new STSLocation(name, ini);
- }
-
- @Override protected String getMacAppName() {
- return "STS.app";
- }
+public class STSLocationProvider extends EclipseProductLocationProvider {
- @Override protected String getUnixAppName() {
- return "STS";
- }
+ private static final EclipseProductDescriptor STS = new StandardProductDescriptor("STS",
+ "STS",
+ "sts",
+ STSLocationProvider.class.getResource("STS.png"),
+ Collections.singleton("springsource")
+ );
- @Override public Pattern getLocationSelectors(OS os) {
- switch (os) {
- case MAC_OS_X:
- return Pattern.compile("^(sts|sts\\.ini|sts\\.app)$", Pattern.CASE_INSENSITIVE);
- case WINDOWS:
- return Pattern.compile("^(stsc?\\.exe|sts\\.ini)$", Pattern.CASE_INSENSITIVE);
- default:
- case UNIX:
- return Pattern.compile("^(sts|sts\\.ini)$", Pattern.CASE_INSENSITIVE);
- }
+ public STSLocationProvider() {
+ super(STS);
}
}
diff --git a/src/installer/lombok/installer/eclipse/StandardProductDescriptor.java b/src/installer/lombok/installer/eclipse/StandardProductDescriptor.java
new file mode 100644
index 00000000..47e103aa
--- /dev/null
+++ b/src/installer/lombok/installer/eclipse/StandardProductDescriptor.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 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.installer.eclipse;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import lombok.installer.OsUtils;
+
+public class StandardProductDescriptor implements EclipseProductDescriptor {
+
+ private static final String USER_HOME = System.getProperty("user.home", ".");
+ private static final String[] WINDOWS_ROOTS = {"\\", "\\Program Files", "\\Program Files (x86)", USER_HOME};
+ private static final String[] MAC_ROOTS = {"/Applications", USER_HOME};
+ private static final String[] UNIX_ROOTS = {USER_HOME};
+
+ private final String productName;
+ private final String windowsName;
+ private final String unixName;
+ private final String macAppName;
+ private final List<String> executableNames;
+ private final List<String> sourceDirsOnWindows;
+ private final List<String> sourceDirsOnMac;
+ private final List<String> sourceDirsOnUnix;
+ private final String iniFileName;
+ private final Pattern locationSelectors;
+ private final String directoryName;
+ private final URL ideIcon;
+
+ public StandardProductDescriptor(String productName, String baseName, String directoryName, URL ideIcon, Collection<String> alternativeDirectoryNames) {
+ this.productName = productName;
+ this.windowsName = baseName + ".exe";
+ this.unixName = baseName;
+ this.macAppName = baseName + ".app";
+ this.executableNames = executableNames(baseName);
+ this.sourceDirsOnWindows = generateAlternatives(WINDOWS_ROOTS, "\\", alternativeDirectoryNames);
+ this.sourceDirsOnMac = generateAlternatives(MAC_ROOTS, "/", alternativeDirectoryNames);
+ this.sourceDirsOnUnix = generateAlternatives(UNIX_ROOTS, "/", alternativeDirectoryNames);
+ this.iniFileName = baseName + ".ini";
+ this.locationSelectors = getLocationSelectors(baseName);
+ this.directoryName = directoryName.toLowerCase();
+ this.ideIcon = ideIcon;
+ }
+
+ @Override public String getProductName() {
+ return productName;
+ }
+
+ @Override public String getWindowsExecutableName() {
+ return windowsName;
+ }
+
+ @Override public String getUnixAppName() {
+ return unixName;
+ }
+
+ @Override public String getMacAppName() {
+ return macAppName;
+ }
+
+ @Override public String getDirectoryName() {
+ return directoryName;
+ }
+
+ @Override public List<String> getExecutableNames() {
+ return executableNames;
+ }
+
+ @Override public List<String> getSourceDirsOnWindows() {
+ return sourceDirsOnWindows;
+ }
+
+ @Override public List<String> getSourceDirsOnMac() {
+ return sourceDirsOnMac;
+ }
+
+ @Override public List<String> getSourceDirsOnUnix() {
+ return sourceDirsOnUnix;
+ }
+
+ @Override public String getIniFileName() {
+ return iniFileName;
+ }
+
+ @Override public Pattern getLocationSelectors() {
+ return locationSelectors;
+ }
+
+ @Override public URL getIdeIcon() {
+ return ideIcon;
+ }
+
+ private static Pattern getLocationSelectors(String baseName) {
+ return Pattern.compile(String.format(platformPattern(), baseName.toLowerCase()), Pattern.CASE_INSENSITIVE);
+ }
+
+ private static String platformPattern() {
+ switch (OsUtils.getOS()) {
+ case MAC_OS_X:
+ return "^(%s|%<s\\.ini|%<s\\.app)$";
+ case WINDOWS:
+ return "^(%sc?\\.exe|%<s\\.ini)$";
+ default:
+ case UNIX:
+ return "^(%s|%<s\\.ini)$";
+ }
+ }
+
+ private static List<String> executableNames(String baseName) {
+ String base = baseName.toLowerCase();
+ return Collections.unmodifiableList(Arrays.asList(base, base + ".app", base + ".exe", base + "c.exe"));
+ }
+
+ private static List<String> generateAlternatives(String[] roots, String pathSeparator, Collection<String> alternatives) {
+ List<String> result = new ArrayList<String>();
+ for (String root : roots) {
+ result.add(concat(root, pathSeparator, ""));
+ for (String alternative : alternatives) {
+ result.add(concat(root, pathSeparator, alternative));
+ }
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ private static String concat(String base, String pathSeparator, String alternative) {
+ if (alternative.isEmpty()) {
+ return base;
+ }
+ if (base.endsWith(pathSeparator)) {
+ return base + alternative.replaceAll("[\\/]", "\\" + pathSeparator);
+ }
+ return base + pathSeparator + alternative.replaceAll("[\\/]", "\\" + pathSeparator);
+ }
+}
diff --git a/src/installer/lombok/installer/eclipse/myeclipse.png b/src/installer/lombok/installer/eclipse/myeclipse.png
new file mode 100644
index 00000000..49c4fab3
--- /dev/null
+++ b/src/installer/lombok/installer/eclipse/myeclipse.png
Binary files differ
diff --git a/src/installer/lombok/installer/eclipse/rhds.png b/src/installer/lombok/installer/eclipse/rhds.png
new file mode 100644
index 00000000..ca7738e6
--- /dev/null
+++ b/src/installer/lombok/installer/eclipse/rhds.png
Binary files differ
diff --git a/src/launch/lombok/launch/AnnotationProcessor.java b/src/launch/lombok/launch/AnnotationProcessor.java
index 35c26b7c..93fba196 100644
--- a/src/launch/lombok/launch/AnnotationProcessor.java
+++ b/src/launch/lombok/launch/AnnotationProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Project Lombok Authors.
+ * Copyright (C) 2014-2016 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
@@ -27,6 +27,7 @@ import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Completion;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
@@ -74,4 +75,15 @@ class AnnotationProcessorHider {
}
}
}
+
+ @SupportedAnnotationTypes("lombok.*")
+ public static class ClaimingProcessor extends AbstractProcessor {
+ @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ return true;
+ }
+
+ @Override public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+ }
}