aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/core/AST.java2
-rw-r--r--src/core/lombok/core/LombokConfiguration.java63
-rw-r--r--src/core/lombok/core/configuration/ConfigurationDataType.java118
-rw-r--r--src/core/lombok/core/configuration/ConfigurationKey.java109
-rw-r--r--src/core/lombok/core/configuration/ConfigurationResolver.java26
-rw-r--r--src/core/lombok/core/configuration/StringResolver.java84
-rw-r--r--src/core/lombok/eclipse/handlers/HandleLog.java2
7 files changed, 386 insertions, 18 deletions
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java
index 954438bd..50eeb399 100644
--- a/src/core/lombok/core/AST.java
+++ b/src/core/lombok/core/AST.java
@@ -36,7 +36,7 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
-import lombok.core.LombokConfiguration.ConfigurationKey;
+import lombok.core.configuration.ConfigurationKey;
/**
* Lombok wraps the AST produced by a target platform into its own AST system, mostly because both Eclipse and javac
diff --git a/src/core/lombok/core/LombokConfiguration.java b/src/core/lombok/core/LombokConfiguration.java
index 88c0be60..40c4a67c 100644
--- a/src/core/lombok/core/LombokConfiguration.java
+++ b/src/core/lombok/core/LombokConfiguration.java
@@ -21,7 +21,11 @@
*/
package lombok.core;
-import java.lang.reflect.Type;
+import java.util.List;
+
+import javax.lang.model.SourceVersion;
+
+import lombok.core.configuration.ConfigurationKey;
public class LombokConfiguration {
@@ -29,23 +33,50 @@ public class LombokConfiguration {
// prevent instantiation
}
- /*
- * Typical usage: use this as a supertypetoken.
- */
- public abstract static class ConfigurationKey<T> {
- private final String keyName;
-
- public ConfigurationKey(String keyName) {
- this.keyName = keyName;
- System.out.println("registering " + keyName);
- }
- }
- @SuppressWarnings("unchecked")
static <T> T read(ConfigurationKey<T> key, AST<?, ?, ?> ast) {
- Type it = key.getClass().getGenericSuperclass();
- if (key.keyName.equals("lombok.log.varName")) return (T)"loggertje";
- if (key.keyName.equals("lombok.log.static")) return (T)Boolean.FALSE;
+// if (key.keyName.equals("lombok.log.varName")) return (T)"loggertje";
+// if (key.keyName.equals("lombok.log.static")) return (T)Boolean.FALSE;
return null;
}
+
+ @SuppressWarnings("rawtypes")
+ public static void main(String[] args) {
+ try { new ConfigurationKey<List<String>>("List<String>") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Integer>("Integer") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Class<?>>("Class<?>") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<SourceVersion>("SourceVersion") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Class>("Class") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Class<Number>>("Class<Number>") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Class<? extends Number>>("Class<? extends Number>") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Class<? super String>>("Class<? super String>") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Number>("Number") {}; } catch (Exception e) { e.printStackTrace();}
+ try { class Between extends ConfigurationKey<String> {
+ public Between() {
+ super("between");
+ }
+ };
+ new Between(){};
+ } catch (Exception e) { e.printStackTrace();}
+
+ try { new ConfigurationKey<String>("more than once") {}; } catch (Exception e) { e.printStackTrace();}
+ try { new ConfigurationKey<Integer>("more than once") {}; } catch (Exception e) { e.printStackTrace();}
+
+ System.out.println(System.identityHashCode(ConfigurationKey.registeredKeys()));
+ System.out.println(System.identityHashCode(ConfigurationKey.registeredKeys()));
+
+ ConfigurationKey<?> first = null;
+ try { first = new ConfigurationKey<Integer>("anint") {}; } catch (Exception e) { e.printStackTrace();}
+ System.out.println(System.identityHashCode(ConfigurationKey.registeredKeys()));
+ System.out.println(System.identityHashCode(ConfigurationKey.registeredKeys()));
+
+ ConfigurationKey<?> second = null;
+ try { second = new ConfigurationKey<Integer>("anint") {}; } catch (Exception e) { e.printStackTrace();}
+ System.out.println(System.identityHashCode(ConfigurationKey.registeredKeys()));
+ System.out.println(System.identityHashCode(ConfigurationKey.registeredKeys()));
+
+ System.out.println(first == second);
+ System.out.println(first.getClass() == second.getClass());
+ System.out.println(first.equals(second));
+ }
}
diff --git a/src/core/lombok/core/configuration/ConfigurationDataType.java b/src/core/lombok/core/configuration/ConfigurationDataType.java
new file mode 100644
index 00000000..5a8c37f1
--- /dev/null
+++ b/src/core/lombok/core/configuration/ConfigurationDataType.java
@@ -0,0 +1,118 @@
+/*
+ * 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.core.configuration;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.Arrays;
+import java.util.List;
+
+public final class ConfigurationDataType {
+ private static final List<Class<?>> SIMPLE_TYPES = Arrays.<Class<?>>asList(String.class, Integer.class, Boolean.class, Long.class, Byte.class, Short.class, Character.class, Float.class, Double.class);
+
+ private final boolean isList;
+ private final Class<?> elementType;
+
+ public static ConfigurationDataType toDataType(Class<? extends ConfigurationKey<?>> keyClass) {
+ if (keyClass.getSuperclass() != ConfigurationKey.class) {
+ throw new IllegalArgumentException("No direct subclass of ConfigurationKey: " + keyClass.getName());
+ }
+
+ Type type = keyClass.getGenericSuperclass();
+ if (!(type instanceof ParameterizedType)) {
+ throw new IllegalArgumentException("Missing type parameter in "+ type);
+ }
+
+ ParameterizedType parameterized = (ParameterizedType) type;
+ Type argumentType = parameterized.getActualTypeArguments()[0];
+
+ boolean isList = false;
+ if (argumentType instanceof ParameterizedType) {
+ ParameterizedType parameterizedArgument = (ParameterizedType) argumentType;
+ if (parameterizedArgument.getRawType() == List.class) {
+ isList = true;
+ argumentType = parameterizedArgument.getActualTypeArguments()[0];
+ }
+ }
+
+ if (SIMPLE_TYPES.contains(argumentType) || isEnum(argumentType)) {
+ return new ConfigurationDataType(isList, (Class<?>)argumentType);
+ }
+
+ if (argumentType instanceof ParameterizedType) {
+ ParameterizedType parameterizedArgument = (ParameterizedType) argumentType;
+ if (parameterizedArgument.getRawType() == Class.class) {
+ Type classType = parameterizedArgument.getActualTypeArguments()[0];
+ if (!(classType instanceof WildcardType)) {
+ throw new IllegalArgumentException("Illegal specific Class type parameter in " + type);
+ }
+ WildcardType wildcard = (WildcardType) classType;
+ if (wildcard.getLowerBounds().length != 0 || wildcard.getUpperBounds().length != 1 || wildcard.getUpperBounds()[0] != Object.class) {
+ throw new IllegalArgumentException("Illegal bound wildcard Class type parameter in " + type);
+ }
+ return new ConfigurationDataType(isList, Class.class);
+ }
+ }
+
+ if (argumentType == Class.class) {
+ return new ConfigurationDataType(isList, Class.class);
+ }
+
+ throw new IllegalArgumentException("Unsupported type parameter in " + type);
+ }
+
+ private ConfigurationDataType(boolean isList, Class<?> elementType) {
+ this.isList = isList;
+ this.elementType = elementType;
+ }
+
+ public boolean isList() {
+ return isList;
+ }
+
+ public Class<?> getElementType() {
+ return elementType;
+ }
+
+ @Override
+ public int hashCode() {
+ return (isList ? 1231 : 1237) + elementType.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ConfigurationDataType)) return false;
+ ConfigurationDataType other = (ConfigurationDataType) obj;
+ return isList == other.isList && elementType == other.elementType;
+ }
+
+ @Override
+ public String toString() {
+ if (isList) return "java.util.List<" + elementType.getName() + ">";
+ return elementType.getName();
+ }
+
+ private static boolean isEnum(Type argumentType) {
+ return argumentType instanceof Class && ((Class<?>) argumentType).isEnum();
+ }
+} \ No newline at end of file
diff --git a/src/core/lombok/core/configuration/ConfigurationKey.java b/src/core/lombok/core/configuration/ConfigurationKey.java
new file mode 100644
index 00000000..aaa673af
--- /dev/null
+++ b/src/core/lombok/core/configuration/ConfigurationKey.java
@@ -0,0 +1,109 @@
+/*
+ * 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.core.configuration;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Describes a configuration key and its type.
+ * <p>
+ * The recommended usage is to create a type token:
+ * <pre>
+ * private static ConfigurationKey&lt;String> KEY = new ConfigurationKey&lt;String>("keyName") {};
+ * </pre>
+ */
+public abstract class ConfigurationKey<T> {
+ private static final Map<String, ConfigurationDataType> registeredKeys = new HashMap<String, ConfigurationDataType>();
+ private static Map<String, ConfigurationDataType> copy;
+
+ private final String keyName;
+ private final ConfigurationDataType type;
+
+ public ConfigurationKey(String keyName) {
+ this.keyName = checkName(keyName);
+ @SuppressWarnings("unchecked")
+ ConfigurationDataType type = ConfigurationDataType.toDataType((Class<? extends ConfigurationKey<?>>)getClass());
+ this.type = type;
+
+ registerKey(keyName, type);
+ }
+
+ public final String getKeyName() {
+ return keyName;
+ }
+
+ public final ConfigurationDataType getType() {
+ return type;
+ }
+
+ @Override
+ public final int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + keyName.hashCode();
+ result = prime * result + type.hashCode();
+ return result;
+ }
+
+ /**
+ * Two configuration are considered equal if and only if their {@code keyName} and {@code type} are equal.
+ */
+ @Override
+ public final boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!(obj instanceof ConfigurationKey)) return false;
+ ConfigurationKey<?> other = (ConfigurationKey<?>) obj;
+ return keyName.equals(other.keyName) && type.equals(other.type);
+ }
+
+ private static String checkName(String keyName) {
+ if (keyName == null) throw new NullPointerException("keyName");
+ if (keyName.contains("=")) throw new IllegalArgumentException("Invalid character '=' in keyName: " + keyName);
+ return keyName;
+ }
+
+ /**
+ * Returns a copy of the currently registered keys.
+ */
+ public static Map<String, ConfigurationDataType> registeredKeys() {
+ synchronized (registeredKeys) {
+ if (copy == null) copy = Collections.unmodifiableMap(new HashMap<String, ConfigurationDataType>(registeredKeys));
+ return copy;
+ }
+ }
+
+ private static void registerKey(String keyName, ConfigurationDataType type) {
+ synchronized (registeredKeys) {
+ ConfigurationDataType existingType = registeredKeys.get(keyName);
+ if (existingType == null) {
+ registeredKeys.put(keyName, type);
+ copy = null;
+ return;
+ }
+ if (!existingType.equals(type)) {
+ throw new IllegalArgumentException("Key '" + keyName + "' already registered with a different type, existing " + existingType + " != provided " + type);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/core/lombok/core/configuration/ConfigurationResolver.java b/src/core/lombok/core/configuration/ConfigurationResolver.java
new file mode 100644
index 00000000..6f52fc6e
--- /dev/null
+++ b/src/core/lombok/core/configuration/ConfigurationResolver.java
@@ -0,0 +1,26 @@
+/*
+ * 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.core.configuration;
+
+public interface ConfigurationResolver {
+ <T> T resolve(ConfigurationKey<T> key);
+}
diff --git a/src/core/lombok/core/configuration/StringResolver.java b/src/core/lombok/core/configuration/StringResolver.java
new file mode 100644
index 00000000..d939d916
--- /dev/null
+++ b/src/core/lombok/core/configuration/StringResolver.java
@@ -0,0 +1,84 @@
+/*
+ * 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.core.configuration;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class StringResolver implements ConfigurationResolver {
+
+ private static final Pattern LINE = Pattern.compile("(?:clear\\s+([^=]+))|(?:(\\S*?)\\s*([-+]?=)\\s*(.*?))");
+
+ public StringResolver(String content) {
+ Map<String, ConfigurationDataType> registeredKeys = ConfigurationKey.registeredKeys();
+ for (String line : content.trim().split("\\s*\\n\\s*")) {
+ if (line.isEmpty() || line.startsWith("#")) continue;
+ Matcher matcher = LINE.matcher(line);
+ System.out.println("\nLINE: " + line);
+
+ String operator = null;
+ String keyName = null;
+ String value = null;
+
+ if (matcher.matches()) {
+ if (matcher.group(1) == null) {
+ keyName = matcher.group(2);
+ operator = matcher.group(3);
+ value = matcher.group(4);
+ } else {
+ keyName = matcher.group(1);
+ operator = "clear";
+ value = null;
+ }
+ ConfigurationDataType type = registeredKeys.get(keyName);
+ if (type == null) {
+ System.out.println("Unknown key " + keyName);
+ } else {
+ boolean listOperator = operator.equals("+=") || operator.equals("-=");
+ if (listOperator && !type.isList()) {
+ System.out.println(keyName + " is not a list");
+ } else if (operator.equals("=") && type.isList()) {
+ System.out.println(keyName + " IS a list");
+ } else {
+ System.out.printf("!! %s %s %s", keyName, operator, value);
+ }
+ }
+ } else {
+ System.out.println("no match:" + line);
+ }
+ }
+ }
+
+ @Override public <T> T resolve(ConfigurationKey<T> key) {
+ return null;
+ }
+
+ public static void main(String[] args) {
+ ConfigurationKey<String> AAP = new ConfigurationKey<String>("aap") {};
+ ConfigurationKey<List<String>> NOOT = new ConfigurationKey<List<String>>("noot") {};
+
+ ConfigurationResolver resolver = new StringResolver(" aap = 3 \naap += 4\n\r noot+=mies\nnoot=wim\nclear noot\nclear aap\r\n#foo-= bar\nblablabla\na=b=c\n\n\nclear test\n\nclear \nclear test=");
+ String aapValue = resolver.resolve(AAP);
+ }
+}
diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java
index 64ec5f96..8c09237e 100644
--- a/src/core/lombok/eclipse/handlers/HandleLog.java
+++ b/src/core/lombok/eclipse/handlers/HandleLog.java
@@ -28,7 +28,7 @@ import java.lang.reflect.Modifier;
import java.util.Arrays;
import lombok.core.AnnotationValues;
-import lombok.core.LombokConfiguration.ConfigurationKey;
+import lombok.core.configuration.ConfigurationKey;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult;