mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 10:18:46 +00:00
Eclipse 3.7 updated some internal AST classes, causing:
NoSuchMethodError: CastExpression.<init> This commit fixes this (now lombok works both <3.7 and 3.7). fixes issue #206
This commit is contained in:
1 parent
35e18b9332
commit
e5e3521378
2 files changed
+91
-10
No files matched your search
@@ -23,6 +23,8 @@ package lombok.eclipse.handlers;
|
||||
|
||||
import static lombok.eclipse.Eclipse.*;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -32,6 +34,7 @@ import java.util.regex.Pattern;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Lombok;
|
||||
import lombok.core.AnnotationValues;
|
||||
import lombok.core.AST.Kind;
|
||||
import lombok.core.handlers.TransformationsUtil;
|
||||
@@ -44,6 +47,7 @@ import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
|
||||
import org.eclipse.jdt.internal.compiler.ast.Annotation;
|
||||
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
|
||||
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
|
||||
import org.eclipse.jdt.internal.compiler.ast.Clinit;
|
||||
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
|
||||
@@ -63,6 +67,7 @@ import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.Statement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
|
||||
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
|
||||
@@ -70,6 +75,7 @@ import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.Binding;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
|
||||
|
||||
/**
|
||||
@@ -655,6 +661,72 @@ public class EclipseHandlerUtil {
|
||||
return problematic;
|
||||
}
|
||||
|
||||
/**
|
||||
* In eclipse 3.7+, the CastExpression constructor was changed from a really weird version to
|
||||
* a less weird one. Unfortunately that means we need to use reflection as we want to be compatible
|
||||
* with eclipse versions before 3.7 and 3.7+.
|
||||
*
|
||||
* @param ref The {@code foo} in {@code (String)foo}.
|
||||
* @param castTo The {@code String} in {@code (String)foo}.
|
||||
*/
|
||||
public static CastExpression makeCastExpression(Expression ref, TypeReference castTo, ASTNode source) {
|
||||
CastExpression result;
|
||||
try {
|
||||
if (castExpressionConstructorIsTypeRefBased) {
|
||||
result = castExpressionConstructor.newInstance(ref, castTo);
|
||||
} else {
|
||||
Expression castToConverted = castTo;
|
||||
|
||||
if (castTo.getClass() == SingleTypeReference.class && !PRIMITIVE_NAMES.contains(
|
||||
" " + new String(((SingleTypeReference)castTo).token) + " ")) {
|
||||
SingleTypeReference str = (SingleTypeReference) castTo;
|
||||
//Why a SingleNameReference instead of a SingleTypeReference you ask? I don't know. It seems dumb. Ask the ecj guys.
|
||||
castToConverted = new SingleNameReference(str.token, 0);
|
||||
castToConverted.bits = (castToConverted.bits & ~Binding.VARIABLE) | Binding.TYPE;
|
||||
castToConverted.sourceStart = str.sourceStart;
|
||||
castToConverted.sourceEnd = str.sourceEnd;
|
||||
Eclipse.setGeneratedBy(castToConverted, source);
|
||||
} else if (castTo.getClass() == QualifiedTypeReference.class) {
|
||||
QualifiedTypeReference qtr = (QualifiedTypeReference) castTo;
|
||||
//Same here, but for the more complex types, they stay types.
|
||||
castToConverted = new QualifiedNameReference(qtr.tokens, qtr.sourcePositions, qtr.sourceStart, qtr.sourceEnd);
|
||||
castToConverted.bits = (castToConverted.bits & ~Binding.VARIABLE) | Binding.TYPE;
|
||||
Eclipse.setGeneratedBy(castToConverted, source);
|
||||
}
|
||||
|
||||
result = castExpressionConstructor.newInstance(ref, castToConverted);
|
||||
}
|
||||
} catch (InvocationTargetException e) {
|
||||
throw Lombok.sneakyThrow(e.getCause());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw Lombok.sneakyThrow(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw Lombok.sneakyThrow(e);
|
||||
}
|
||||
|
||||
Eclipse.setGeneratedBy(result, source);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final String PRIMITIVE_NAMES = " int long float double char short byte boolean ";
|
||||
private static final Constructor<CastExpression> castExpressionConstructor;
|
||||
private static final boolean castExpressionConstructorIsTypeRefBased;
|
||||
|
||||
static {
|
||||
Constructor<?> constructor = null;
|
||||
for (Constructor<?> ctor : CastExpression.class.getConstructors()) {
|
||||
if (ctor.getParameterTypes().length != 2) continue;
|
||||
constructor = ctor;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Constructor<CastExpression> constructor_ = (Constructor<CastExpression>) constructor;
|
||||
castExpressionConstructor = constructor_;
|
||||
|
||||
castExpressionConstructorIsTypeRefBased =
|
||||
(castExpressionConstructor.getParameterTypes()[1] == TypeReference.class);
|
||||
}
|
||||
|
||||
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
|
||||
static Annotation[] getAndRemoveAnnotationParameter(Annotation annotation, String annotationName) {
|
||||
|
||||
|
||||
@@ -510,9 +510,9 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
|
||||
other.modifiers |= ClassFileConstants.AccFinal;
|
||||
Eclipse.setGeneratedBy(other, source);
|
||||
char[] typeName = typeDecl.name;
|
||||
Expression targetType;
|
||||
TypeReference targetType;
|
||||
if (typeDecl.typeParameters == null || typeDecl.typeParameters.length == 0) {
|
||||
targetType = new SingleNameReference(((TypeDeclaration)type.get()).name, p);
|
||||
targetType = new SingleTypeReference(typeName, p);
|
||||
Eclipse.setGeneratedBy(targetType, source);
|
||||
other.type = new SingleTypeReference(typeName, p);
|
||||
Eclipse.setGeneratedBy(other.type, source);
|
||||
@@ -530,8 +530,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
|
||||
}
|
||||
NameReference oRef = new SingleNameReference(new char[] { 'o' }, p);
|
||||
Eclipse.setGeneratedBy(oRef, source);
|
||||
other.initialization = new CastExpression(oRef, targetType);
|
||||
Eclipse.setGeneratedBy(other.initialization, source);
|
||||
other.initialization = EclipseHandlerUtil.makeCastExpression(oRef, targetType, source);
|
||||
statements.add(other);
|
||||
}
|
||||
}
|
||||
@@ -547,8 +546,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
|
||||
|
||||
ThisReference thisReference = new ThisReference(pS, pE);
|
||||
Eclipse.setGeneratedBy(thisReference, source);
|
||||
CastExpression castThisRef = new CastExpression(thisReference, generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_OBJECT));
|
||||
Eclipse.setGeneratedBy(castThisRef, source);
|
||||
CastExpression castThisRef = EclipseHandlerUtil.makeCastExpression(thisReference, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), source);
|
||||
castThisRef.sourceStart = pS; castThisRef.sourceEnd = pE;
|
||||
|
||||
otherCanEqual.arguments = new Expression[] {castThisRef};
|
||||
@@ -625,8 +623,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
|
||||
equalsCall.receiver = createFieldAccessor(field, fieldAccess, source);
|
||||
equalsCall.selector = "equals".toCharArray();
|
||||
Expression equalsArg = createFieldAccessor(field, fieldAccess, source, otherName);
|
||||
CastExpression castEqualsArg = new CastExpression(equalsArg, generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_OBJECT));
|
||||
Eclipse.setGeneratedBy(castEqualsArg, source);
|
||||
CastExpression castEqualsArg = EclipseHandlerUtil.makeCastExpression(equalsArg, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), source);
|
||||
castEqualsArg.sourceStart = pS; castEqualsArg.sourceEnd = pE;
|
||||
equalsCall.arguments = new Expression[] { castEqualsArg };
|
||||
UnaryExpression fieldsNotEqual = new UnaryExpression(equalsCall, OperatorIds.NOT);
|
||||
@@ -762,9 +759,8 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
|
||||
TypeReference intRef = TypeReference.baseTypeReference(TypeIds.T_int, 0);
|
||||
intRef.sourceStart = pS; intRef.sourceEnd = pE;
|
||||
Eclipse.setGeneratedBy(intRef, source);
|
||||
CastExpression expr = new CastExpression(xorParts, intRef);
|
||||
CastExpression expr = EclipseHandlerUtil.makeCastExpression(xorParts, intRef, source);
|
||||
expr.sourceStart = pS; expr.sourceEnd = pE;
|
||||
Eclipse.setGeneratedBy(expr, source);
|
||||
return expr;
|
||||
}
|
||||
|
||||
@@ -779,4 +775,17 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
|
||||
Eclipse.setGeneratedBy(ref, source);
|
||||
return ref;
|
||||
}
|
||||
|
||||
private TypeReference generateQualifiedTypeRef(ASTNode source, char[]... varNames) {
|
||||
int pS = source.sourceStart, pE = source.sourceEnd;
|
||||
long p = (long)pS << 32 | pE;
|
||||
|
||||
TypeReference ref;
|
||||
|
||||
long[] poss = Eclipse.poss(source, varNames.length);
|
||||
if (varNames.length > 1) ref = new QualifiedTypeReference(varNames, poss);
|
||||
else ref = new SingleTypeReference(varNames[0], p);
|
||||
Eclipse.setGeneratedBy(ref, source);
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user