Search in sources :

Example 51 with EclipseNode

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);
        }
    }
}
Also used : SetGeneratedByVisitor(lombok.eclipse.handlers.SetGeneratedByVisitor) CompilationUnitDeclaration(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) EclipseNode(lombok.eclipse.EclipseNode)

Example 52 with EclipseNode

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;
}
Also used : CompilationUnitDeclaration(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration) EclipseNode(lombok.eclipse.EclipseNode) EclipseAST(lombok.eclipse.EclipseAST) TransformEclipseAST(lombok.eclipse.TransformEclipseAST)

Example 53 with EclipseNode

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.");
    }
}
Also used : MemberValuePair(org.eclipse.jdt.internal.compiler.ast.MemberValuePair) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) ArrayList(java.util.ArrayList) EclipseNode(lombok.eclipse.EclipseNode) ArrayInitializer(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer)

Example 54 with EclipseNode

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);
}
Also used : MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) EclipseNode(lombok.eclipse.EclipseNode)

Example 55 with EclipseNode

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;
}
Also used : EclipseNode(lombok.eclipse.EclipseNode) ToString(lombok.ToString)

Aggregations

EclipseNode (lombok.eclipse.EclipseNode)55 TypeDeclaration (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)25 ArrayList (java.util.ArrayList)20 FieldDeclaration (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)19 MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)16 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)12 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)11 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)11 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)10 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)9 SingleTypeReference (org.eclipse.jdt.internal.compiler.ast.SingleTypeReference)9 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)7 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)7 ThisReference (org.eclipse.jdt.internal.compiler.ast.ThisReference)7 ParameterizedQualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference)6 ParameterizedSingleTypeReference (org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference)6 ReturnStatement (org.eclipse.jdt.internal.compiler.ast.ReturnStatement)6 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)6 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)5 Argument (org.eclipse.jdt.internal.compiler.ast.Argument)5