Java Code Examples for org.codehaus.groovy.ast.ClassNode#implementsInterface()

The following examples show how to use org.codehaus.groovy.ast.ClassNode#implementsInterface() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ClassCompletionVerifier.java    From groovy with Apache License 2.0 6 votes vote down vote up
private void checkClassExtendsAllSelfTypes(ClassNode node) {
    int modifiers = node.getModifiers();
    if (!isInterface(modifiers)) {
        for (ClassNode anInterface : GeneralUtils.getInterfacesAndSuperInterfaces(node)) {
            if (Traits.isTrait(anInterface)) {
                LinkedHashSet<ClassNode> selfTypes = new LinkedHashSet<ClassNode>();
                for (ClassNode type : Traits.collectSelfTypes(anInterface, selfTypes, true, false)) {
                    if (type.isInterface() && !node.implementsInterface(type)) {
                        addError(getDescription(node)
                                + " implements " + getDescription(anInterface)
                                + " but does not implement self type " + getDescription(type),
                                anInterface);
                    } else if (!type.isInterface() && !node.isDerivedFrom(type)) {
                        addError(getDescription(node)
                                        + " implements " + getDescription(anInterface)
                                        + " but does not extend self type " + getDescription(type),
                                anInterface);
                    }
                }
            }
        }
    }
}
 
Example 2
Source File: WideningCategories.java    From groovy with Apache License 2.0 6 votes vote down vote up
private static void addMostSpecificInterface(ClassNode interfaceNode, List<ClassNode> nodes) {
    if (nodes.isEmpty()) nodes.add(interfaceNode);
    for (int i = 0, nodesSize = nodes.size(); i < nodesSize; i++) {
        final ClassNode node = nodes.get(i);
        if (node.equals(interfaceNode)||node.implementsInterface(interfaceNode)) {
            // a more specific interface exists in the list, keep it
            return;
        }
        if (interfaceNode.implementsInterface(node)) {
            // the interface being added is more specific than the one in the list, replace it
            nodes.set(i, interfaceNode);
            return;
        }
    }
    // if we reach this point, this means the interface is new
    nodes.add(interfaceNode);
}
 
Example 3
Source File: ClosureCreationInterceptingVerifier.java    From pushfish-android with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void visitClass(ClassNode node) {
    if (node.implementsInterface(ClassHelper.GENERATED_CLOSURE_Type)) {
        RulesVisitor.visitGeneratedClosure(node);
        RuleVisitor.visitGeneratedClosure(node);
    }

    super.visitClass(node);
}
 
Example 4
Source File: OptimizingStatementWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
public void visitClass(final ClassNode node) {
    this.optimizeMethodCall = !node.implementsInterface(GROOVY_INTERCEPTABLE_TYPE);
    this.node = node;
    this.scope = nonStaticScope;
    super.visitClass(node);
    this.scope = null;
    this.node = null;
}
 
Example 5
Source File: Verifier.java    From groovy with Apache License 2.0 5 votes vote down vote up
private boolean isAssignable(ClassNode node, ClassNode testNode) {
    if (node.isArray() && testNode.isArray()) {
        return isArrayAssignable(node.getComponentType(), testNode.getComponentType());
    }
    if (testNode.isInterface()) {
        if (node.equals(testNode) || node.implementsInterface(testNode)) return true;
    }
    return node.isDerivedFrom(testNode);
}
 
Example 6
Source File: Verifier.java    From groovy with Apache License 2.0 5 votes vote down vote up
protected void addPropertyMethod(MethodNode method) {
    classNode.addMethod(method);
    markAsGenerated(classNode, method);
    // GROOVY-4415 / GROOVY-4645: check that there's no abstract method which corresponds to this one
    String methodName = method.getName();
    Parameter[] parameters = method.getParameters();
    ClassNode methodReturnType = method.getReturnType();
    for (MethodNode node : classNode.getAbstractMethods()) {
        if (!node.getDeclaringClass().equals(classNode)) continue;
        if (node.getName().equals(methodName) && node.getParameters().length == parameters.length) {
            if (parameters.length == 1) {
                // setter
                ClassNode abstractMethodParameterType = node.getParameters()[0].getType();
                ClassNode methodParameterType = parameters[0].getType();
                if (!methodParameterType.isDerivedFrom(abstractMethodParameterType) && !methodParameterType.implementsInterface(abstractMethodParameterType)) {
                    continue;
                }
            }
            ClassNode nodeReturnType = node.getReturnType();
            if (!methodReturnType.isDerivedFrom(nodeReturnType) && !methodReturnType.implementsInterface(nodeReturnType)) {
                continue;
            }
            // matching method, remove abstract status and use the same body
            node.setModifiers(node.getModifiers() ^ ACC_ABSTRACT);
            node.setCode(method.getCode());
        }
    }
}
 
Example 7
Source File: StaticInvocationWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
private boolean compatibleArgumentType(final ClassNode argumentType, final ClassNode paramType) {
    if (argumentType == null) return false;
    if (ClassHelper.getWrapper(argumentType).equals(ClassHelper.getWrapper(paramType))) return true;
    if (paramType.isInterface()) return argumentType.implementsInterface(paramType);
    if (paramType.isArray() && argumentType.isArray())
        return compatibleArgumentType(argumentType.getComponentType(), paramType.getComponentType());
    return ClassHelper.getWrapper(argumentType).isDerivedFrom(ClassHelper.getWrapper(paramType));
}
 
Example 8
Source File: WideningCategories.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Determines if the source class implements an interface or subclasses the target type.
 * This method takes the {@link org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode lowest
 * upper bound class node} type into account, allowing to remove unnecessary casts.
 * @param source the type of interest
 * @param targetType the target type of interest
 */
public static boolean implementsInterfaceOrSubclassOf(final ClassNode source, final ClassNode targetType) {
    if (source.isDerivedFrom(targetType) || source.implementsInterface(targetType)) return true;
    if (targetType instanceof WideningCategories.LowestUpperBoundClassNode) {
        WideningCategories.LowestUpperBoundClassNode lub = (WideningCategories.LowestUpperBoundClassNode) targetType;
        if (implementsInterfaceOrSubclassOf(source, lub.getSuperClass())) return true;
        for (ClassNode classNode : lub.getInterfaces()) {
            if (source.implementsInterface(classNode)) return true;
        }
    }
    return false;
}
 
Example 9
Source File: UnionTypeClassNode.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
public boolean implementsInterface(final ClassNode classNode) {
    for (ClassNode delegate : delegates) {
        if (delegate.implementsInterface(classNode)) return true;
    }
    return false;
}
 
Example 10
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static void removeMethodInSuperInterface(final List<MethodNode> toBeRemoved, final MethodNode one, final MethodNode two) {
    ClassNode oneDC = one.getDeclaringClass();
    ClassNode twoDC = two.getDeclaringClass();
    if (oneDC.implementsInterface(twoDC)) {
        toBeRemoved.add(two);
    } else {
        toBeRemoved.add(one);
    }
}
 
Example 11
Source File: ClosureCreationInterceptingVerifier.java    From Pushjet-Android with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void visitClass(ClassNode node) {
    if (node.implementsInterface(ClassHelper.GENERATED_CLOSURE_Type)) {
        RulesVisitor.visitGeneratedClosure(node);
        RuleVisitor.visitGeneratedClosure(node);
    }

    super.visitClass(node);
}
 
Example 12
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 5 votes vote down vote up
public static boolean implementsInterfaceOrIsSubclassOf(final ClassNode type, final ClassNode superOrInterface) {
    boolean result = (type.equals(superOrInterface)
            || type.isDerivedFrom(superOrInterface)
            || type.implementsInterface(superOrInterface)
            || type == UNKNOWN_PARAMETER_TYPE);
    if (result) {
        return true;
    }
    if (superOrInterface instanceof WideningCategories.LowestUpperBoundClassNode) {
        WideningCategories.LowestUpperBoundClassNode cn = (WideningCategories.LowestUpperBoundClassNode) superOrInterface;
        result = implementsInterfaceOrIsSubclassOf(type, cn.getSuperClass());
        if (result) {
            for (ClassNode interfaceNode : cn.getInterfaces()) {
                result = type.implementsInterface(interfaceNode);
                if (!result) break;
            }
        }
        if (result) return true;
    } else if (superOrInterface instanceof UnionTypeClassNode) {
        UnionTypeClassNode union = (UnionTypeClassNode) superOrInterface;
        for (ClassNode delegate : union.getDelegates()) {
            if (implementsInterfaceOrIsSubclassOf(type, delegate)) return true;
        }
    }
    if (type.isArray() && superOrInterface.isArray()) {
        return implementsInterfaceOrIsSubclassOf(type.getComponentType(), superOrInterface.getComponentType());
    }
    if (GROOVY_OBJECT_TYPE.equals(superOrInterface) && !type.isInterface() && isBeingCompiled(type)) {
        return true;
    }
    return false;
}
 
Example 13
Source File: AstUtils.java    From Pushjet-Android with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public static MethodNode getGeneratedClosureImplMethod(ClassNode classNode) {
    if (!classNode.implementsInterface(ClassHelper.GENERATED_CLOSURE_Type)) {
        throw new IllegalArgumentException("expecting generated closure class node");
    }

    List<MethodNode> doCallMethods = classNode.getDeclaredMethods("doCall");
    return doCallMethods.get(0);
}
 
Example 14
Source File: AstUtils.java    From pushfish-android with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public static MethodNode getGeneratedClosureImplMethod(ClassNode classNode) {
    if (!classNode.implementsInterface(ClassHelper.GENERATED_CLOSURE_Type)) {
        throw new IllegalArgumentException("expecting generated closure class node");
    }

    List<MethodNode> doCallMethods = classNode.getDeclaredMethods("doCall");
    return doCallMethods.get(0);
}
 
Example 15
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 4 votes vote down vote up
private static boolean isCovariant(final ClassNode left, final ClassNode right) {
    if (left.isArray() && right.isArray()) {
        return isCovariant(left.getComponentType(), right.getComponentType());
    }
    return (left.isDerivedFrom(right) || left.implementsInterface(right));
}
 
Example 16
Source File: GeneralUtils.java    From groovy with Apache License 2.0 4 votes vote down vote up
public static boolean isOrImplements(final ClassNode type, final ClassNode interfaceType) {
    return type.equals(interfaceType) || type.implementsInterface(interfaceType);
}
 
Example 17
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 4 votes vote down vote up
public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final ClassNode right, final Expression rightExpression, final boolean allowConstructorCoercion) {
    ClassNode leftRedirect = left.redirect();
    ClassNode rightRedirect = right.redirect();
    if (leftRedirect == rightRedirect) return true;

    if (leftRedirect.isArray() && rightRedirect.isArray()) {
        return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType(), rightExpression, false);
    }

    if (right == VOID_TYPE || right == void_WRAPPER_TYPE) {
        return left == VOID_TYPE || left == void_WRAPPER_TYPE;
    }

    if ((isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect))) {
        if (BigDecimal_TYPE == leftRedirect) {
            // any number can be assigned to a big decimal
            return true;
        }
        if (BigInteger_TYPE == leftRedirect) {
            return WideningCategories.isBigIntCategory(getUnwrapper(rightRedirect)) || rightRedirect.isDerivedFrom(BigInteger_TYPE);
        }
    }

    // if rightExpression is null and leftExpression is not a primitive type, it's ok
    boolean rightExpressionIsNull = (rightExpression instanceof ConstantExpression && ((ConstantExpression) rightExpression).isNullExpression());
    if (rightExpressionIsNull && !isPrimitiveType(left)) {
        return true;
    }

    // on an assignment everything that can be done by a GroovyCast is allowed

    // anything can be assigned to an Object, String, Boolean or Class typed variable
    if (isWildcardLeftHandSide(leftRedirect) && !(boolean_TYPE.equals(left) && rightExpressionIsNull)) return true;

    // char as left expression
    if (leftRedirect == char_TYPE && rightRedirect == STRING_TYPE) {
        if (rightExpression instanceof ConstantExpression) {
            String value = rightExpression.getText();
            return value.length() == 1;
        }
    }
    if (leftRedirect == Character_TYPE && (rightRedirect == STRING_TYPE || rightExpressionIsNull)) {
        return rightExpressionIsNull || (rightExpression instanceof ConstantExpression && rightExpression.getText().length() == 1);
    }

    // if left is Enum and right is String or GString we do valueOf
    if (leftRedirect.isDerivedFrom(Enum_Type) && (rightRedirect == GSTRING_TYPE || rightRedirect == STRING_TYPE)) {
        return true;
    }

    // if right is array, map or collection we try invoking the constructor
    if (allowConstructorCoercion && isGroovyConstructorCompatible(rightExpression)) {
        // TODO: in case of the array we could maybe make a partial check
        if (leftRedirect.isArray() && rightRedirect.isArray()) {
            return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType());
        } else if (rightRedirect.isArray() && !leftRedirect.isArray()) {
            return false;
        }
        return true;
    }

    // simple check on being subclass
    if (right.isDerivedFrom(left) || (left.isInterface() && right.implementsInterface(left))) return true;

    // if left and right are primitives or numbers allow
    if (isPrimitiveType(leftRedirect) && isPrimitiveType(rightRedirect)) return true;
    if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) return true;

    // left is a float/double and right is a BigDecimal
    if (WideningCategories.isFloatingCategory(leftRedirect) && BigDecimal_TYPE.equals(rightRedirect)) {
        return true;
    }

    if (GROOVY_OBJECT_TYPE.equals(leftRedirect) && isBeingCompiled(right)) {
        return true;
    }

    if (left.isGenericsPlaceHolder()) {
        // GROOVY-7307
        GenericsType[] genericsTypes = left.getGenericsTypes();
        if (genericsTypes != null && genericsTypes.length == 1) {
            // should always be the case, but safe guard is better
            return genericsTypes[0].isCompatibleWith(right);
        }
    }

    // GROOVY-7316: It is an apparently legal thing to allow this. It's not type safe, but it is allowed...
    return right.isGenericsPlaceHolder();
}
 
Example 18
Source File: ExternalizeVerifierASTTransformation.java    From groovy with Apache License 2.0 4 votes vote down vote up
private static boolean implementsExternalizable(ClassNode cNode) {
    return cNode.implementsInterface(EXTERNALIZABLE_TYPE);
}
 
Example 19
Source File: StaticTypesLambdaWriter.java    From groovy with Apache License 2.0 4 votes vote down vote up
@Override
public void writeLambda(final LambdaExpression expression) {
    ClassNode functionalInterface = getFunctionalInterfaceType(expression);
    if (functionalInterface == null || !functionalInterface.isInterface()) {
        super.writeLambda(expression);
        return;
    }

    MethodNode abstractMethod = findSAM(functionalInterface.redirect());
    if (abstractMethod == null) {
        super.writeLambda(expression);
        return;
    }

    if (!expression.isSerializable() && functionalInterface.implementsInterface(SERIALIZABLE_TYPE)) {
        expression.setSerializable(true);
    }

    ClassNode enclosingClass = controller.getClassNode();
    int modifiers = ACC_FINAL | ACC_PUBLIC | ACC_SYNTHETIC;
    if (enclosingClass.isInterface()) modifiers |= ACC_STATIC;
    ClassNode lambdaClass = getOrAddLambdaClass(expression, modifiers, abstractMethod);
    MethodNode lambdaMethod = lambdaClass.getMethods("doCall").get(0);

    boolean canDeserialize = enclosingClass.hasMethod(createDeserializeLambdaMethodName(lambdaClass), createDeserializeLambdaMethodParams());
    if (!canDeserialize) {
        if (expression.isSerializable()) {
            addDeserializeLambdaMethodForEachLambdaExpression(expression, lambdaClass);
            addDeserializeLambdaMethod();
        }
        newGroovyLambdaWrapperAndLoad(lambdaClass, expression, isAccessingInstanceMembersOfEnclosingClass(lambdaMethod));
    }

    MethodVisitor mv = controller.getMethodVisitor();
    mv.visitInvokeDynamicInsn(
            abstractMethod.getName(),
            createAbstractMethodDesc(functionalInterface.redirect(), lambdaClass),
            createBootstrapMethod(enclosingClass.isInterface(), expression.isSerializable()),
            createBootstrapMethodArguments(createMethodDescriptor(abstractMethod), H_INVOKEVIRTUAL, lambdaClass, lambdaMethod, expression.isSerializable())
    );
    if (expression.isSerializable()) {
        mv.visitTypeInsn(CHECKCAST, "java/io/Serializable");
    }

    OperandStack operandStack = controller.getOperandStack();
    operandStack.replace(functionalInterface.redirect(), 1);
}
 
Example 20
Source File: InvocationWriter.java    From groovy with Apache License 2.0 4 votes vote down vote up
protected boolean writeDirectMethodCall(final MethodNode target, final boolean implicitThis, final Expression receiver, final TupleExpression args) {
    if (target == null) return false;

    String methodName = target.getName();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();
    ClassNode declaringClass = target.getDeclaringClass();
    ClassNode classNode = controller.getClassNode();

    MethodVisitor mv = controller.getMethodVisitor();
    int opcode = INVOKEVIRTUAL;
    if (target.isStatic()) {
        opcode = INVOKESTATIC;
    } else if (declaringClass.isInterface()) {
        opcode = INVOKEINTERFACE;
    } else if (target.isPrivate() || AsmClassGenerator.isSuperExpression(receiver)) {
        opcode = INVOKESPECIAL;
    }

    // handle receiver
    int argumentsToRemove = 0;
    if (opcode != INVOKESTATIC) {
        if (receiver != null) {
            // load receiver if not static invocation
            // todo: fix inner class case
            if (implicitThis
                    && classNode.getOuterClass() != null
                    && !classNode.isDerivedFrom(declaringClass)
                    && !classNode.implementsInterface(declaringClass)) {
                // we are calling an outer class method
                compileStack.pushImplicitThis(false);
                if (controller.isInGeneratedFunction()) {
                    new VariableExpression("thisObject").visit(controller.getAcg());
                } else {
                    Expression expr = new PropertyExpression(new ClassExpression(declaringClass), "this");
                    expr.visit(controller.getAcg());
                }
            } else {
                compileStack.pushImplicitThis(implicitThis);
                receiver.visit(controller.getAcg());
            }
            operandStack.doGroovyCast(declaringClass);
            compileStack.popImplicitThis();
            argumentsToRemove += 1;
        } else {
            mv.visitIntInsn(ALOAD,0);
            operandStack.push(classNode);
            argumentsToRemove += 1;
        }
    }

    int stackSize = operandStack.getStackLength();

    String owner = BytecodeHelper.getClassInternalName(declaringClass);
    ClassNode receiverType = receiver != null ? controller.getTypeChooser().resolveType(receiver, classNode) : declaringClass;
    if (opcode == INVOKEVIRTUAL && ClassHelper.OBJECT_TYPE.equals(declaringClass)) {
        // avoid using a narrowed type if the method is defined on object because it can interfere
        // with delegate type inference in static compilation mode and trigger a ClassCastException
        receiverType = declaringClass;
    }
    if (opcode == INVOKEVIRTUAL) {
        if (!receiverType.equals(declaringClass)
                && !ClassHelper.OBJECT_TYPE.equals(declaringClass)
                && !receiverType.isArray()
                && !receiverType.isInterface()
                && !ClassHelper.isPrimitiveType(receiverType) // e.g int.getClass()
                && receiverType.isDerivedFrom(declaringClass)) {

            owner = BytecodeHelper.getClassInternalName(receiverType);
            ClassNode top = operandStack.getTopOperand();
            if (!receiverType.equals(top)) {
                mv.visitTypeInsn(CHECKCAST, owner);
            }
        } else if (target.isPublic()
                && (!receiverType.equals(declaringClass) && !Modifier.isPublic(declaringClass.getModifiers()))
                && receiverType.isDerivedFrom(declaringClass) && !Objects.equals(receiverType.getPackageName(), classNode.getPackageName())) {
            // GROOVY-6962: package private class, public method
            owner = BytecodeHelper.getClassInternalName(receiverType);
        }
    }

    loadArguments(args.getExpressions(), target.getParameters());

    String desc = BytecodeHelper.getMethodDescriptor(target.getReturnType(), target.getParameters());
    mv.visitMethodInsn(opcode, owner, methodName, desc, declaringClass.isInterface());
    ClassNode ret = target.getReturnType().redirect();
    if (ret == ClassHelper.VOID_TYPE) {
        ret = ClassHelper.OBJECT_TYPE;
        mv.visitInsn(ACONST_NULL);
    }
    argumentsToRemove += (operandStack.getStackLength()-stackSize);
    controller.getOperandStack().remove(argumentsToRemove);
    controller.getOperandStack().push(ret);
    return true;
}