use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class PatchDelegate method generateDelegateMethods.
/*
* We may someday finish this method. Steps to be completed:
*
* (A) Turn any Parameterized anythings into non-parameterized versions. Resolving parameterized stuff will definitely not work safely.
* (B) scope.problemReporter() will need to return a noop reporter as various errors are marked off.
* (C) Find a way to do _something_ for references to typevars (i.e. 'T') which are declared on the method itself.
* (D) getTypeBinding isn't public, so call it via reflection.
*/
// private static TypeBinding safeResolveAndErase(TypeReference ref, Scope scope) {
// if (ref.resolvedType != null) {
// return ref.resolvedType.isValidBinding() ? ref.resolvedType : null;
// }
//
// try {
// TypeBinding bind = ref.getTypeBinding(scope);
// if (!bind.isValidBinding()) return null;
// } catch (AbortCompilation e) {
// return null;
// }
// return bind.erasure();
// }
/*
* Not using this because calling clone.resolveType() taints a bunch of caches and reports erroneous errors.
*/
// private static void removeExistingMethods(List<BindingTuple> list, TypeDeclaration decl, ClassScope scope) {
// for (AbstractMethodDeclaration methodDecl : decl.methods) {
// if (!(methodDecl instanceof MethodDeclaration)) continue;
// MethodDeclaration md = (MethodDeclaration) methodDecl;
// char[] name = md.selector;
// TypeBinding[] args = md.arguments == null ? new TypeBinding[0] : new TypeBinding[md.arguments.length];
// for (int i = 0; i < args.length; i++) {
// TypeReference clone = Eclipse.copyType(md.arguments[i].type, md.arguments[i]);
// args[i] = clone.resolveType(scope).erasure(); // This is the problematic line
// }
// Iterator<BindingTuple> it = list.iterator();
// methods:
// while (it.hasNext()) {
// MethodBinding mb = it.next().parameterized;
// if (!Arrays.equals(mb.selector, name)) continue;
// int paramLen = mb.parameters == null ? 0 : mb.parameters.length;
// if (paramLen != args.length) continue;
// if (md.typeParameters == null || md.typeParameters.length == 0) {
// for (int i = 0; i < paramLen; i++) {
// if (!mb.parameters[i].erasure().isEquivalentTo(args[i])) continue methods;
// }
// } else {
// for (int i = 0; i < paramLen; i++) {
// if (!mb.parameters[i].erasure().isEquivalentTo(args[i])) ;
// }
// //BUG #???: We erase the method's parameter types using the class scope, but we should be using the method scope.
// // In practice this is no problem UNLESS the method has type parameters, such as <T> T[] toArray(T[] in).
// // In this case the class scope cannot resolve the T[] parameter and erase it to Object[], which is a big problem because
// // it would mean manually writing <X> X[] toArray(X[] in) does NOT stop lombok from ALSO trying to make the delegated toArray method,
// // thus causing an error (2 methods with post-erasure duplicate signatures). Our 'fix' for this is to treat any method with type parameters
// // as if each parameter's type matches anything else; so, if the name matches and the parameter count, we DONT generate it, even if its just
// // an overloaded method.
// //
// // The reason we do this now is because making that MethodScope properly is effectively impossible at this step, so we need to do the resolving
// // ourselves, which involves chasing down array bindings (T[]), following the path down type variables, i.e. <X extends Y, Y extends T>, and then
// // resolving the final result of this exercise against the class scope.
//
// // When this crappy incomplete workaround of ours occurs, we end up in this else block, which does nothing and thus we fall through and remove
// // the method.
// }
// it.remove(); // Method already exists in this class - don't create a delegating implementation.
// }
// }
// }
private static void generateDelegateMethods(EclipseNode typeNode, List<BindingTuple> methods, DelegateReceiver delegateReceiver) {
CompilationUnitDeclaration top = (CompilationUnitDeclaration) typeNode.top().get();
for (BindingTuple pair : methods) {
EclipseNode annNode = typeNode.getAst().get(pair.responsible);
MethodDeclaration method = createDelegateMethod(pair.fieldName, typeNode, pair, top.compilationResult, annNode, delegateReceiver);
if (method != null) {
SetGeneratedByVisitor visitor = new SetGeneratedByVisitor(annNode.get());
method.traverse(visitor, ((TypeDeclaration) typeNode.get()).scope);
injectMethod(typeNode, method);
}
}
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class PatchExtensionMethod method getTypeNode.
public static EclipseNode getTypeNode(TypeDeclaration decl) {
CompilationUnitDeclaration cud = decl.scope.compilationUnitScope().referenceContext;
EclipseAST astNode = TransformEclipseAST.getAST(cud, false);
EclipseNode node = astNode.get(decl);
if (node == null) {
astNode = TransformEclipseAST.getAST(cud, true);
node = astNode.get(decl);
}
return node;
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleSneakyThrows method handle.
@Override
public void handle(AnnotationValues<SneakyThrows> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.SNEAKY_THROWS_FLAG_USAGE, "@SneakyThrows");
List<String> exceptionNames = annotation.getRawExpressions("value");
List<DeclaredException> exceptions = new ArrayList<DeclaredException>();
MemberValuePair[] memberValuePairs = source.memberValuePairs();
if (memberValuePairs == null || memberValuePairs.length == 0) {
exceptions.add(new DeclaredException("java.lang.Throwable", source));
} else {
Expression arrayOrSingle = memberValuePairs[0].value;
final Expression[] exceptionNameNodes;
if (arrayOrSingle instanceof ArrayInitializer) {
exceptionNameNodes = ((ArrayInitializer) arrayOrSingle).expressions;
} else
exceptionNameNodes = new Expression[] { arrayOrSingle };
if (exceptionNames.size() != exceptionNameNodes.length) {
annotationNode.addError("LOMBOK BUG: The number of exception classes in the annotation isn't the same pre- and post- guessing.");
}
int idx = 0;
for (String exceptionName : exceptionNames) {
if (exceptionName.endsWith(".class"))
exceptionName = exceptionName.substring(0, exceptionName.length() - 6);
exceptions.add(new DeclaredException(exceptionName, exceptionNameNodes[idx++]));
}
}
EclipseNode owner = annotationNode.up();
switch(owner.getKind()) {
// return handleField(annotationNode, (FieldDeclaration)owner.get(), exceptions);
case METHOD:
handleMethod(annotationNode, (AbstractMethodDeclaration) owner.get(), exceptions);
break;
default:
annotationNode.addError("@SneakyThrows is legal only on methods and constructors.");
}
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleSynchronized method preHandle.
@Override
public void preHandle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) {
EclipseNode methodNode = annotationNode.up();
if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof MethodDeclaration))
return;
MethodDeclaration method = (MethodDeclaration) methodNode.get();
if (method.isAbstract())
return;
createLockField(annotation, annotationNode, method.isStatic(), false);
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleToString method getTypeName.
public static String getTypeName(EclipseNode type) {
String typeName = getSingleTypeName(type);
EclipseNode upType = type.up();
while (upType.getKind() == Kind.TYPE) {
typeName = getSingleTypeName(upType) + "." + typeName;
upType = upType.up();
}
return typeName;
}
Aggregations