mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 10:18:46 +00:00
[configuration] ongoing work on the typing and resolving
This commit is contained in:
1 parent
404956374e
commit
43ead7d65f
7 files changed
+386
-18
No files matched your search
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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<String> KEY = new ConfigurationKey<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user