Search in sources :

Example 1 with BlockScope

use of org.eclipse.jdt.internal.compiler.lookup.BlockScope in project lombok by rzwitserloot.

the class PatchExtensionMethod method getApplicableExtensionMethods.

static List<Extension> getApplicableExtensionMethods(EclipseNode typeNode, Annotation ann, TypeBinding receiverType) {
    List<Extension> extensions = new ArrayList<Extension>();
    if ((typeNode != null) && (ann != null) && (receiverType != null)) {
        BlockScope blockScope = ((TypeDeclaration) typeNode.get()).initializerScope;
        EclipseNode annotationNode = typeNode.getNodeFor(ann);
        AnnotationValues<ExtensionMethod> annotation = createAnnotation(ExtensionMethod.class, annotationNode);
        boolean suppressBaseMethods = false;
        try {
            suppressBaseMethods = annotation.getInstance().suppressBaseMethods();
        } catch (AnnotationValueDecodeFail fail) {
            fail.owner.setError(fail.getMessage(), fail.idx);
        }
        for (Object extensionMethodProvider : annotation.getActualExpressions("value")) {
            if (extensionMethodProvider instanceof ClassLiteralAccess) {
                TypeBinding binding = ((ClassLiteralAccess) extensionMethodProvider).type.resolveType(blockScope);
                if (binding == null)
                    continue;
                if (!binding.isClass() && !binding.isEnum())
                    continue;
                Extension e = new Extension();
                e.extensionMethods = getApplicableExtensionMethodsDefinedInProvider(typeNode, (ReferenceBinding) binding, receiverType);
                e.suppressBaseMethods = suppressBaseMethods;
                extensions.add(e);
            }
        }
    }
    return extensions;
}
Also used : AnnotationValueDecodeFail(lombok.core.AnnotationValues.AnnotationValueDecodeFail) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) ArrayList(java.util.ArrayList) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) BlockScope(org.eclipse.jdt.internal.compiler.lookup.BlockScope) EclipseNode(lombok.eclipse.EclipseNode) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) ExtensionMethod(lombok.experimental.ExtensionMethod) ClassLiteralAccess(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess)

Example 2 with BlockScope

use of org.eclipse.jdt.internal.compiler.lookup.BlockScope in project spoon by INRIA.

the class ReferenceBuilder method buildTypeReferenceInternal.

private <T> CtTypeReference<T> buildTypeReferenceInternal(CtTypeReference<T> typeReference, TypeReference type, Scope scope) {
    if (type == null) {
        return null;
    }
    CtTypeReference<?> currentReference = typeReference;
    for (int position = type.getTypeName().length - 1; position >= 0; position--) {
        if (currentReference == null) {
            break;
        }
        this.jdtTreeBuilder.getContextBuilder().enter(currentReference, type);
        if (type.annotations != null && type.annotations.length - 1 <= position && type.annotations[position] != null && type.annotations[position].length > 0) {
            for (Annotation annotation : type.annotations[position]) {
                if (scope instanceof ClassScope) {
                    annotation.traverse(this.jdtTreeBuilder, (ClassScope) scope);
                } else if (scope instanceof BlockScope) {
                    annotation.traverse(this.jdtTreeBuilder, (BlockScope) scope);
                } else {
                    annotation.traverse(this.jdtTreeBuilder, (BlockScope) null);
                }
            }
        }
        if (type.getTypeArguments() != null && type.getTypeArguments().length - 1 <= position && type.getTypeArguments()[position] != null && type.getTypeArguments()[position].length > 0) {
            currentReference.getActualTypeArguments().clear();
            for (TypeReference typeArgument : type.getTypeArguments()[position]) {
                if (typeArgument instanceof Wildcard || typeArgument.resolvedType instanceof WildcardBinding || typeArgument.resolvedType instanceof TypeVariableBinding) {
                    currentReference.addActualTypeArgument(buildTypeParameterReference(typeArgument, scope));
                } else {
                    currentReference.addActualTypeArgument(buildTypeReference(typeArgument, scope));
                }
            }
        } else if ((type instanceof ParameterizedSingleTypeReference || type instanceof ParameterizedQualifiedTypeReference) && !isTypeArgumentExplicit(type.getTypeArguments())) {
            for (CtTypeReference<?> actualTypeArgument : currentReference.getActualTypeArguments()) {
                actualTypeArgument.setImplicit(true);
                if (actualTypeArgument instanceof CtArrayTypeReference) {
                    ((CtArrayTypeReference) actualTypeArgument).getComponentType().setImplicit(true);
                }
            }
        }
        if (type instanceof Wildcard && typeReference instanceof CtTypeParameterReference) {
            ((CtTypeParameterReference) typeReference).setBoundingType(buildTypeReference(((Wildcard) type).bound, scope));
        }
        this.jdtTreeBuilder.getContextBuilder().exit(type);
        currentReference = currentReference.getDeclaringType();
    }
    return typeReference;
}
Also used : TypeVariableBinding(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding) WildcardBinding(org.eclipse.jdt.internal.compiler.lookup.WildcardBinding) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) ClassScope(org.eclipse.jdt.internal.compiler.lookup.ClassScope) CtTypeParameterReference(spoon.reflect.reference.CtTypeParameterReference) Wildcard(org.eclipse.jdt.internal.compiler.ast.Wildcard) CtTypeReference(spoon.reflect.reference.CtTypeReference) BlockScope(org.eclipse.jdt.internal.compiler.lookup.BlockScope) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) CtArrayTypeReference(spoon.reflect.reference.CtArrayTypeReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtArrayTypeReference(spoon.reflect.reference.CtArrayTypeReference)

Example 3 with BlockScope

use of org.eclipse.jdt.internal.compiler.lookup.BlockScope in project lombok by rzwitserloot.

the class HandleHelper method handle.

@Override
public void handle(AnnotationValues<Helper> annotation, Annotation ast, EclipseNode annotationNode) {
    handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper");
    EclipseNode annotatedType = annotationNode.up();
    EclipseNode containingBlock = annotatedType == null ? null : annotatedType.directUp();
    Statement[] origStatements = getStatementsFromAstNode(containingBlock == null ? null : containingBlock.get());
    if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) {
        annotationNode.addError("@Helper is legal only on method-local classes.");
        return;
    }
    TypeDeclaration annotatedType_ = (TypeDeclaration) annotatedType.get();
    int indexOfType = -1;
    for (int i = 0; i < origStatements.length; i++) {
        if (origStatements[i] == annotatedType_) {
            indexOfType = i;
            break;
        }
    }
    final List<String> knownMethodNames = new ArrayList<String>();
    for (AbstractMethodDeclaration methodOfHelper : annotatedType_.methods) {
        if (!(methodOfHelper instanceof MethodDeclaration))
            continue;
        char[] name = methodOfHelper.selector;
        if (name != null && name.length > 0 && name[0] != '<')
            knownMethodNames.add(new String(name));
    }
    Collections.sort(knownMethodNames);
    final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
    final char[] helperName = new char[annotatedType_.name.length + 1];
    final boolean[] helperUsed = new boolean[1];
    helperName[0] = '$';
    System.arraycopy(annotatedType_.name, 0, helperName, 1, helperName.length - 1);
    ASTVisitor visitor = new ASTVisitor() {

        @Override
        public boolean visit(MessageSend messageSend, BlockScope scope) {
            if (messageSend.receiver instanceof ThisReference) {
                if ((((ThisReference) messageSend.receiver).bits & ASTNode.IsImplicitThis) == 0)
                    return true;
            } else if (messageSend.receiver != null)
                return true;
            char[] name = messageSend.selector;
            if (name == null || name.length == 0 || name[0] == '<')
                return true;
            String n = new String(name);
            if (Arrays.binarySearch(knownMethodNames_, n) < 0)
                return true;
            messageSend.receiver = new SingleNameReference(helperName, messageSend.nameSourcePosition);
            helperUsed[0] = true;
            return true;
        }
    };
    for (int i = indexOfType + 1; i < origStatements.length; i++) {
        origStatements[i].traverse(visitor, null);
    }
    if (!helperUsed[0]) {
        annotationNode.addWarning("No methods of this helper class are ever used.");
        return;
    }
    Statement[] newStatements = new Statement[origStatements.length + 1];
    System.arraycopy(origStatements, 0, newStatements, 0, indexOfType + 1);
    System.arraycopy(origStatements, indexOfType + 1, newStatements, indexOfType + 2, origStatements.length - indexOfType - 1);
    LocalDeclaration decl = new LocalDeclaration(helperName, 0, 0);
    decl.modifiers |= ClassFileConstants.AccFinal;
    AllocationExpression alloc = new AllocationExpression();
    alloc.type = new SingleTypeReference(annotatedType_.name, 0L);
    decl.initialization = alloc;
    decl.type = new SingleTypeReference(annotatedType_.name, 0L);
    SetGeneratedByVisitor sgbvVisitor = new SetGeneratedByVisitor(annotationNode.get());
    decl.traverse(sgbvVisitor, null);
    newStatements[indexOfType + 1] = decl;
    setStatementsOfAstNode(containingBlock.get(), newStatements);
}
Also used : LocalDeclaration(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) SwitchStatement(org.eclipse.jdt.internal.compiler.ast.SwitchStatement) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) ArrayList(java.util.ArrayList) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) ASTVisitor(org.eclipse.jdt.internal.compiler.ASTVisitor) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) BlockScope(org.eclipse.jdt.internal.compiler.lookup.BlockScope) EclipseNode(lombok.eclipse.EclipseNode) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)

Aggregations

BlockScope (org.eclipse.jdt.internal.compiler.lookup.BlockScope)3 ArrayList (java.util.ArrayList)2 EclipseNode (lombok.eclipse.EclipseNode)2 TypeDeclaration (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)2 AnnotationValueDecodeFail (lombok.core.AnnotationValues.AnnotationValueDecodeFail)1 ExtensionMethod (lombok.experimental.ExtensionMethod)1 ASTVisitor (org.eclipse.jdt.internal.compiler.ASTVisitor)1 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)1 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)1 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)1 ClassLiteralAccess (org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess)1 LocalDeclaration (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)1 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)1 MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)1 ParameterizedQualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference)1 ParameterizedSingleTypeReference (org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference)1 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)1 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)1 SingleTypeReference (org.eclipse.jdt.internal.compiler.ast.SingleTypeReference)1 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)1