mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-18 00:15:24 +00:00
[#688] Bugfix for eclipse: syntax highlighting would break amongst many other features if using @Setter and most other features.
This commit is contained in:
1 parent
b37a95a6a4
commit
f30485c91f
2 files changed
+141
-4
No files matched your search
@@ -2,6 +2,7 @@ Lombok Changelog
|
||||
----------------
|
||||
|
||||
### v1.14.1 "Edgy Guinea Pig"
|
||||
* BUGFIX: syntax highlighting in eclipse will become weird and auto-complete may stop working amongst other eclipse features in v1.14.0 (regression from v1.12.6). [Issue #688](https://code.google.com/p/projectlombok/issues/detail?id=688)
|
||||
* FEATURE: Added `@Tolerate`; put this annotation on any method or constructor and lombok will skip it when considering whether or not to generate a method or constructor. This is useful if the types of the parameters of your method do not clash with what lombok would generate.
|
||||
* FEATURE: Added config key `lombok.getter.noIsPrefix`, which lets you disable use and generation of `isFoo()`, instead going with `getFoo()`, for {@code boolean} fields.
|
||||
* BUGFIX: Errors in the eclipse log with `IndexOutOfBound: 2` in `ASTConverter.convertType`. [Issue #686](https://code.google.com/p/projectlombok/issues/detail?id=686)
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
package lombok.core;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
@@ -41,7 +43,8 @@ public abstract class ReferenceFieldAugment<T, F> {
|
||||
* @throws NullPointerException if {@code type}, {@code fieldType} or {@code name} is {@code null}
|
||||
*/
|
||||
public static <T, F> ReferenceFieldAugment<T, F> augment(Class<T> type, Class<? super F> fieldType, String name) {
|
||||
return new MapFieldAugment<T, F>();
|
||||
ReferenceFieldAugment<T, F> ret = tryCreateReflectionAugment(type, fieldType, name);
|
||||
return ret != null ? ret : new MapFieldAugment<T, F>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +61,56 @@ public abstract class ReferenceFieldAugment<T, F> {
|
||||
* @throws NullPointerException if {@code type}, {@code fieldType} or {@code name} is {@code null}
|
||||
*/
|
||||
public static <T, F> ReferenceFieldAugment<T, F> augmentWeakField(Class<T> type, Class<? super F> fieldType, String name) {
|
||||
return new MapWeakFieldAugment<T, F>();
|
||||
ReferenceFieldAugment<T, F> ret = tryCreateReflectionAugment(type, fieldType, name);
|
||||
return ret != null ? ret : new MapWeakFieldAugment<T, F>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a reflection-based augment which will directly access the listed field name. If this field does not exist or the field
|
||||
* is not capable of storing the requested type, {@code null} is returned instead.
|
||||
*/
|
||||
private static <T, F> ReferenceFieldAugment<T, F> tryCreateReflectionAugment(Class<T> type, Class<? super F> fieldType, String name) {
|
||||
Field f = findField(type, name);
|
||||
if (f != null && typeIsAssignmentCompatible(f.getType(), fieldType)) return new ReflectionFieldAugment<T, F>(f, fieldType);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the named <em>instance</em> field in the type, or in any of its supertypes, regardless of its access modifier. It's set as accessible and returned if found.
|
||||
*/
|
||||
private static Field findField(Class<?> type, String name) {
|
||||
while (type != null) {
|
||||
try {
|
||||
Field f = type.getDeclaredField(name);
|
||||
if (!Modifier.isStatic(f.getModifiers())) {
|
||||
f.setAccessible(true);
|
||||
return f;
|
||||
}
|
||||
} catch (NoSuchFieldException fallthrough) {}
|
||||
type = type.getSuperclass();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean typeIsAssignmentCompatible(Class<?> fieldType, Class<?> wantedType) {
|
||||
if (Modifier.isFinal(fieldType.getModifiers())) return false;
|
||||
if (Modifier.isStatic(fieldType.getModifiers())) return false;
|
||||
|
||||
if (fieldType == java.lang.Object.class) return true;
|
||||
if (fieldType == wantedType) return true;
|
||||
|
||||
if (fieldType.isPrimitive()) return fieldType == wantedType;
|
||||
if (wantedType == int.class && (fieldType == Number.class || fieldType == Integer.class)) return true;
|
||||
if (wantedType == long.class && (fieldType == Number.class || fieldType == Long.class)) return true;
|
||||
if (wantedType == short.class && (fieldType == Number.class || fieldType == Short.class)) return true;
|
||||
if (wantedType == byte.class && (fieldType == Number.class || fieldType == Byte.class)) return true;
|
||||
if (wantedType == char.class && (fieldType == Number.class || fieldType == Character.class)) return true;
|
||||
if (wantedType == float.class && (fieldType == Number.class || fieldType == Float.class)) return true;
|
||||
if (wantedType == double.class && (fieldType == Number.class || fieldType == Double.class)) return true;
|
||||
if (wantedType == boolean.class && fieldType == Boolean.class) return true;
|
||||
|
||||
return fieldType.isAssignableFrom(wantedType);
|
||||
}
|
||||
|
||||
private ReferenceFieldAugment() {
|
||||
@@ -71,7 +123,7 @@ public abstract class ReferenceFieldAugment<T, F> {
|
||||
public abstract F get(T object);
|
||||
|
||||
/**
|
||||
* @throws NullPointerException if {@code object} or {@code expected} is {@code null}
|
||||
* @throws NullPointerException if {@code object} or {@code value} is {@code null}
|
||||
*/
|
||||
public final void set(T object, F value) {
|
||||
getAndSet(object, value);
|
||||
@@ -79,7 +131,7 @@ public abstract class ReferenceFieldAugment<T, F> {
|
||||
|
||||
/**
|
||||
* @return the value of the field <strong>before</strong> the operation.
|
||||
* @throws NullPointerException if {@code object} or {@code expected} is {@code null}
|
||||
* @throws NullPointerException if {@code object} or {@code value} is {@code null}.
|
||||
*/
|
||||
public abstract F getAndSet(T object, F value);
|
||||
|
||||
@@ -107,6 +159,90 @@ public abstract class ReferenceFieldAugment<T, F> {
|
||||
*/
|
||||
public abstract F compareAndSet(T object, F expected, F value);
|
||||
|
||||
private static class ReflectionFieldAugment<T, F> extends ReferenceFieldAugment<T, F> {
|
||||
private final Field field;
|
||||
private final Class<F> targetType;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ReflectionFieldAugment(Field field, Class<? super F> targetType) {
|
||||
this.field = field;
|
||||
this.targetType = (Class<F>) targetType;
|
||||
}
|
||||
|
||||
@Override public F get(T object) {
|
||||
checkNotNull(object, "object");
|
||||
try {
|
||||
return targetType.cast(field.get(object));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public F getAndSet(T object, F value) {
|
||||
checkNotNull(object, "object");
|
||||
checkNotNull(value, "value");
|
||||
try {
|
||||
F oldValue = targetType.cast(field.get(object));
|
||||
field.set(object, value);
|
||||
return oldValue;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public F clear(T object) {
|
||||
checkNotNull(object, "object");
|
||||
try {
|
||||
F oldValue = targetType.cast(field.get(object));
|
||||
field.set(object, null);
|
||||
return oldValue;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public F compareAndClear(T object, F expected) {
|
||||
checkNotNull(object, "object");
|
||||
checkNotNull(expected, "expected");
|
||||
try {
|
||||
F result = targetType.cast(field.get(object));
|
||||
if (result == null) return null;
|
||||
if (!expected.equals(result)) return result;
|
||||
field.set(object, null);
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public F setIfAbsent(T object, F value) {
|
||||
checkNotNull(object, "object");
|
||||
checkNotNull(value, "value");
|
||||
try {
|
||||
F result = targetType.cast(field.get(object));
|
||||
if (result != null) return result;
|
||||
field.set(object, value);
|
||||
return value;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public F compareAndSet(T object, F expected, F value) {
|
||||
checkNotNull(object, "object");
|
||||
checkNotNull(expected, "expected");
|
||||
checkNotNull(value, "value");
|
||||
try {
|
||||
F result = targetType.cast(field.get(object));
|
||||
if (!expected.equals(result)) return result;
|
||||
field.set(object, value);
|
||||
return value;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MapFieldAugment<T, F> extends ReferenceFieldAugment<T, F> {
|
||||
final Map<T, Object> values = new WeakHashMap<T, Object>();
|
||||
|
||||
|
||||
Reference in new issue
Block a user