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

The following examples show how to use org.codehaus.groovy.ast.ClassNode#getInterfaces() . 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: ClassNodeUtils.java    From groovy with Apache License 2.0 6 votes vote down vote up
/**
 * Return the (potentially inherited) field of the classnode.
 *
 * @param classNode the classnode
 * @param fieldName the name of the field
 * @return the field or null if not found
 */
public static FieldNode getField(ClassNode classNode, String fieldName) {
    ClassNode node = classNode;
    Set<String> visited = new HashSet<>();
    while (node != null) {
        FieldNode fn = node.getDeclaredField(fieldName);
        if (fn != null) return fn;
        ClassNode[] interfaces = node.getInterfaces();
        for (ClassNode iNode : interfaces) {
            if (visited.contains(iNode.getName())) continue;
            FieldNode ifn = getField(iNode, fieldName);
            visited.add(iNode.getName());
            if (ifn != null) return ifn;
        }
        node = node.getSuperClass();
    }
    return null;
}
 
Example 2
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 6 votes vote down vote up
private static int getMaximumInterfaceDistance(final ClassNode c, final ClassNode interfaceClass) {
    // -1 means a mismatch
    if (c == null) return -1;
    // 0 means a direct match
    if (c.equals(interfaceClass)) return 0;
    ClassNode[] interfaces = c.getInterfaces();
    int max = -1;
    for (ClassNode anInterface : interfaces) {
        int sub = getMaximumInterfaceDistance(anInterface, interfaceClass);
        // we need to keep the -1 to track the mismatch, a +1
        // by any means could let it look like a direct match
        // we want to add one, because there is an interface between
        // the interface we search for and the interface we are in.
        if (sub != -1) {
            sub += 1;
        }
        // we are interested in the longest path only
        max = Math.max(max, sub);
    }
    // we do not add one for super classes, only for interfaces
    int superClassMax = getMaximumInterfaceDistance(c.getSuperClass(), interfaceClass);
    return Math.max(max, superClassMax);
}
 
Example 3
Source File: CompleteElementHandler.java    From netbeans with Apache License 2.0 5 votes vote down vote up
private Map<FieldSignature, CompletionItem> getFieldsInner(ClassNode source, ClassNode node, String prefix, int anchor, int level) {
    boolean leaf = (level == 0);

    /* Move this whole block away, context information should be in CompletionContext */
    ClassDefinition definition = loadDefinition(node);
    ClassNode typeNode = definition.getNode();
    String typeName = typeNode.getName();
    // In cases like 1.^ we have current type name "int" but indexer won't find anything for such a primitive
    if ("int".equals(typeName)) { // NOI18N
        typeName = "java.lang.Integer"; // NOI18N
    }
    context.setTypeName(typeName);
    /**/
    
    Map<FieldSignature, CompletionItem> result = new HashMap<>();

    GroovyElementsProvider groovyProvider = new GroovyElementsProvider();
    fillSuggestions(groovyProvider.getFields(context), result);
    fillSuggestions(groovyProvider.getStaticFields(context), result);

    fillSuggestions(JavaElementHandler.forCompilationInfo(info).getFields(typeNode.getName(), prefix, anchor, leaf), result);

    CompletionProviderHandler providerHandler = new CompletionProviderHandler();
    fillSuggestions(providerHandler.getFields(context), result);
    fillSuggestions(providerHandler.getStaticFields(context), result);

    if (typeNode.getSuperClass() != null) {
        fillSuggestions(getFieldsInner(source, typeNode.getSuperClass(), prefix, anchor, level + 1), result);
    } else if (leaf) {
        fillSuggestions(JavaElementHandler.forCompilationInfo(info).getFields("java.lang.Object", prefix, anchor, false), result); // NOI18N
    }

    for (ClassNode inter : typeNode.getInterfaces()) {
        fillSuggestions(getFieldsInner(source, inter, prefix, anchor, level + 1), result);
    }
    
    fillSuggestions(TransformationHandler.getFields(index, typeNode, prefix, anchor), result);

    return result;
}
 
Example 4
Source File: BytecodeHelper.java    From groovy with Apache License 2.0 5 votes vote down vote up
public static String getGenericsSignature(ClassNode node) {
    if (!usesGenericsInClassSignature(node)) return null;
    GenericsType[] genericsTypes = node.getGenericsTypes();
    StringBuilder ret = new StringBuilder(100);
    getGenericsTypeSpec(ret, genericsTypes);
    GenericsType extendsPart = new GenericsType(node.getUnresolvedSuperClass(false));
    writeGenericsBounds(ret, extendsPart, true);
    ClassNode[] interfaces = node.getInterfaces();
    for (ClassNode anInterface : interfaces) {
        GenericsType interfacePart = new GenericsType(anInterface);
        writeGenericsBounds(ret, interfacePart, false);
    }
    return ret.toString();
}
 
Example 5
Source File: BytecodeHelper.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static boolean usesGenericsInClassSignature(ClassNode node) {
    if (!node.isUsingGenerics()) return false;
    if (hasGenerics(node)) return true;
    ClassNode sclass = node.getUnresolvedSuperClass(false);
    if (sclass.isUsingGenerics()) return true;
    ClassNode[] interfaces = node.getInterfaces();
    if (interfaces != null) {
        for (ClassNode anInterface : interfaces) {
            if (anInterface.isUsingGenerics()) return true;
        }
    }
    return false;
}
 
Example 6
Source File: ClassCompletionVerifier.java    From groovy with Apache License 2.0 5 votes vote down vote up
private void checkImplementsAndExtends(ClassNode node) {
    ClassNode cn = node.getSuperClass();
    if (cn.isInterface() && !node.isInterface()) {
        addError("You are not allowed to extend the " + getDescription(cn) + ", use implements instead.", node);
    }
    for (ClassNode anInterface : node.getInterfaces()) {
        cn = anInterface;
        if (!cn.isInterface()) {
            addError("You are not allowed to implement the " + getDescription(cn) + ", use extends instead.", node);
        }
    }
}
 
Example 7
Source File: WideningCategories.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Given two class nodes, returns the first common supertype, or the class itself
 * if there are equal. For example, Double and Float would return Number, while
 * Set and String would return Object.
 *
 * This method is not guaranteed to return a class node which corresponds to a
 * real type. For example, if two types have more than one interface in common
 * and are not in the same hierarchy branch, then the returned type will be a
 * virtual type implementing all those interfaces.
 *
 * Calls to this method are supposed to be made with resolved generics. This means
 * that you can have wildcards, but no placeholder.
 *
 * @param a first class node
 * @param b second class node
 * @return first common supertype
 */
public static ClassNode lowestUpperBound(ClassNode a, ClassNode b) {
    ClassNode lub = lowestUpperBound(a, b, null, null);
    if (lub==null || !lub.isUsingGenerics()) return lub;
    // types may be parameterized. If so, we must ensure that generic type arguments
    // are made compatible

    if (lub instanceof LowestUpperBoundClassNode) {
        // no parent super class representing both types could be found
        // or both class nodes implement common interfaces which may have
        // been parameterized differently.
        // We must create a classnode for which the "superclass" is potentially parameterized
        // plus the interfaces
        ClassNode superClass = lub.getSuperClass();
        ClassNode psc = superClass.isUsingGenerics()?parameterizeLowestUpperBound(superClass, a, b, lub):superClass;

        ClassNode[] interfaces = lub.getInterfaces();
        ClassNode[] pinterfaces = new ClassNode[interfaces.length];
        for (int i = 0, interfacesLength = interfaces.length; i < interfacesLength; i++) {
            final ClassNode icn = interfaces[i];
            if (icn.isUsingGenerics()) {
                pinterfaces[i] = parameterizeLowestUpperBound(icn, a, b, lub);
            } else {
                pinterfaces[i] = icn;
            }
        }

        return new LowestUpperBoundClassNode(((LowestUpperBoundClassNode)lub).name, psc, pinterfaces);
    } else {
        return parameterizeLowestUpperBound(lub, a, b, lub);

    }
}
 
Example 8
Source File: Traits.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Collects all the self types that a type should extend or implement, given
 * the traits is implements.
 * @param receiver a class node that may implement a trait
 * @param selfTypes a collection where the list of self types will be written
 * @param checkInterfaces should the interfaces that the node implements be collected too
 * @param checkSuper should we collect from the superclass too
 * @return the selfTypes collection itself
 * @since 2.4.0
 */
public static LinkedHashSet<ClassNode> collectSelfTypes(
        ClassNode receiver,
        LinkedHashSet<ClassNode> selfTypes,
        boolean checkInterfaces,
        boolean checkSuper) {
    if (Traits.isTrait(receiver)) {
        List<AnnotationNode> annotations = receiver.getAnnotations(SELFTYPE_CLASSNODE);
        for (AnnotationNode annotation : annotations) {
            Expression value = annotation.getMember("value");
            if (value instanceof ClassExpression) {
                selfTypes.add(value.getType());
            } else if (value instanceof ListExpression) {
                List<Expression> expressions = ((ListExpression) value).getExpressions();
                for (Expression expression : expressions) {
                    if (expression instanceof ClassExpression) {
                        selfTypes.add(expression.getType());
                    }
                }
            }
        }
    }
    if (checkInterfaces) {
        ClassNode[] interfaces = receiver.getInterfaces();
        for (ClassNode anInterface : interfaces) {
            collectSelfTypes(anInterface, selfTypes, true, checkSuper);
        }
    }

    if (checkSuper) {
        ClassNode superClass = receiver.getSuperClass();
        if (superClass != null) {
            collectSelfTypes(superClass, selfTypes, checkInterfaces, true);
        }
    }
    return selfTypes;
}
 
Example 9
Source File: Traits.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Collects all interfaces of a class node, but reverses the order of the declaration of direct interfaces
 * of this class node. This is used to make sure a trait implementing A,B where both A and B have the same
 * method will take the method from B (latest), aligning the behavior with categories.
 * @param cNode a class node
 * @param interfaces ordered set of interfaces
 */
public static LinkedHashSet<ClassNode> collectAllInterfacesReverseOrder(ClassNode cNode, LinkedHashSet<ClassNode> interfaces) {
    if (cNode.isInterface())
        interfaces.add(cNode);

    ClassNode[] directInterfaces = cNode.getInterfaces();
    for (int i = directInterfaces.length-1; i >=0 ; i--) {
        final ClassNode anInterface = directInterfaces[i];
        interfaces.add(GenericsUtils.parameterizeType(cNode,anInterface));
        collectAllInterfacesReverseOrder(anInterface, interfaces);
    }
    return interfaces;
}
 
Example 10
Source File: UnionTypeClassNode.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
public ClassNode[] getInterfaces() {
    Set<ClassNode> nodes = new LinkedHashSet<ClassNode>();
    for (ClassNode delegate : delegates) {
        ClassNode[] interfaces = delegate.getInterfaces();
        if (interfaces != null) Collections.addAll(nodes, interfaces);
    }
    return nodes.toArray(ClassNode.EMPTY_ARRAY);
}
 
Example 11
Source File: GenericsVisitor.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
public void visitClass(ClassNode node) {
    boolean error = checkWildcard(node);
    if (error) return;
    boolean isAnon = node instanceof InnerClassNode && ((InnerClassNode) node).isAnonymous();
    checkGenericsUsage(node.getUnresolvedSuperClass(false), node.getSuperClass(), isAnon ? true : null);
    ClassNode[] interfaces = node.getInterfaces();
    for (ClassNode anInterface : interfaces) {
        checkGenericsUsage(anInterface, anInterface.redirect());
    }
    node.visitContents(this);
}
 
Example 12
Source File: CompilationUnit.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static int getSuperInterfaceCount(final ClassNode classNode) {
    int count = 1;
    for (ClassNode face : classNode.getInterfaces()) {
        count = Math.max(count, getSuperInterfaceCount(face) + 1);
    }
    return count;
}
 
Example 13
Source File: ClassNodeUtils.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Adds methods from interfaces and parent interfaces. Existing entries in the methods map take precedence.
 * Methods from interfaces visited early take precedence over later ones.
 *
 * @param cNode The ClassNode
 * @param methodsMap A map of existing methods to alter
 */
public static void addDeclaredMethodsFromAllInterfaces(ClassNode cNode, Map<String, MethodNode> methodsMap) {
    List<?> cnInterfaces = Arrays.asList(cNode.getInterfaces());
    ClassNode parent = cNode.getSuperClass();
    while (parent != null && !parent.equals(ClassHelper.OBJECT_TYPE)) {
        ClassNode[] interfaces = parent.getInterfaces();
        for (ClassNode iface : interfaces) {
            if (!cnInterfaces.contains(iface)) {
                methodsMap.putAll(iface.getDeclaredMethodsMap());
            }
        }
        parent = parent.getSuperClass();
    }
}
 
Example 14
Source File: ClassNodeUtils.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Adds methods from all interfaces. Existing entries in the methods map
 * take precedence. Methods from interfaces visited early take precedence
 * over later ones.
 *
 * @param cNode The ClassNode
 * @param methodsMap A map of existing methods to alter
 */
public static void addDeclaredMethodsFromInterfaces(ClassNode cNode, Map<String, MethodNode> methodsMap) {
    for (ClassNode iface : cNode.getInterfaces()) {
        Map<String, MethodNode> declaredMethods = iface.getDeclaredMethodsMap();
        for (Map.Entry<String, MethodNode> entry : declaredMethods.entrySet()) {
            if (entry.getValue().getDeclaringClass().isInterface() && (entry.getValue().getModifiers() & ACC_SYNTHETIC) == 0) {
                methodsMap.putIfAbsent(entry.getKey(), entry.getValue());
            }
        }
    }
}
 
Example 15
Source File: FindTypeUsagesVisitor.java    From netbeans with Apache License 2.0 5 votes vote down vote up
@Override
public void visitClass(ClassNode clazz) {
    if (isEquals(clazz.getSuperClass())) {
        // Oh my goodness I have absolutely no idea why the hack getSuperClass() doesn't return valid initiated superclass
        // and the method with a weird name getUnresolvedSuperClass(false) is actually returning resolved super class (with
        // line/column numbers set)
        usages.add(new ASTUtils.FakeASTNode(clazz.getUnresolvedSuperClass(false), clazz.getSuperClass().getNameWithoutPackage()));
    }
    for (ClassNode interfaceNode : clazz.getInterfaces()) {
        addIfEquals(interfaceNode);
    }
    super.visitClass(clazz);
}
 
Example 16
Source File: FindDirectSubtypesOnly.java    From netbeans with Apache License 2.0 5 votes vote down vote up
@Override
public void visitClass(ClassNode clazz) {
    if (findingFqn.equals(ElementUtils.getTypeName(clazz.getSuperClass()))) {
        // Oh my goodness I have absolutely no idea why the hack getSuperClass() doesn't return valid initiated superclass
        // and the method with a weird name getUnresolvedSuperClass(false) is actually returning resolved super class (with
        // line/column numbers set)
        usages.add(new FakeASTNode(clazz.getUnresolvedSuperClass(false), clazz.getSuperClass().getNameWithoutPackage()));
    }
    for (ClassNode interfaceNode : clazz.getInterfaces()) {
        if (findingFqn.equals(ElementUtils.getTypeName(interfaceNode))) {
            usages.add(new FakeASTNode(ElementUtils.getType(interfaceNode), ElementUtils.getTypeName(interfaceNode)));
        }
    }
    super.visitClass(clazz);
}
 
Example 17
Source File: VariableScopeVisitor.java    From netbeans with Apache License 2.0 5 votes vote down vote up
private void addClassNodeOccurrences(ClassNode visitedNode, ClassNode findingNode) {
    final String findingName = ElementUtils.getTypeName(findingNode);
    final ClassNode superClass = visitedNode.getUnresolvedSuperClass(false);
    final ClassNode[] interfaces = visitedNode.getInterfaces();

    // Check if the caret is on the ClassNode itself
    if (findingName.equals(visitedNode.getName())) {
        occurrences.add(new FakeASTNode(visitedNode, visitedNode.getNameWithoutPackage()));
    }

    // Check if the caret is on the parent type
    if (superClass.getLineNumber() > 0 && superClass.getColumnNumber() > 0) {
        if (findingName.equals(superClass.getName())) {
            occurrences.add(new FakeASTNode(superClass, superClass.getNameWithoutPackage()));
        }
    }

    // Check all implemented interfaces
    for (ClassNode interfaceNode : interfaces) {
        if (interfaceNode.getLineNumber() > 0 && interfaceNode.getColumnNumber() > 0) {
            if (findingName.equals(interfaceNode.getName())) {
                occurrences.add(new FakeASTNode(interfaceNode, interfaceNode.getNameWithoutPackage()));
            }
        }
    }

    // Check all class level annotations
    for (AnnotationNode annotation : visitedNode.getAnnotations(findingNode)) {
        addAnnotationOccurrences(annotation, findingNode);
    }
}
 
Example 18
Source File: CompleteElementHandler.java    From netbeans with Apache License 2.0 4 votes vote down vote up
private Map<MethodSignature, CompletionItem> getMethodsInner(
        ClassNode source,
        ClassNode node,
        String prefix,
        int anchor,
        int level,
        Set<AccessLevel> access,
        boolean nameOnly) {

    boolean leaf = (level == 0);
    Set<AccessLevel> modifiedAccess = AccessLevel.update(access, source, node);

    Map<MethodSignature, CompletionItem> result = new TreeMap<>(new Comparator<MethodSignature>() {

        @Override
        public int compare(MethodSignature method1, MethodSignature method2) {
            // Different method name --> just compare as normal Strings
            if (!method1.getName().equals(method2.getName())) {
                return method1.getName().compareTo(method2.getName());
            }
            // Method with lower 'parameter count' should be always first
            if (method1.getParameters().length < method2.getParameters().length) {
                return -1;
            }
            if (method1.getParameters().length > method2.getParameters().length) {
                return 1;
            }
            // Same number of parameters --> compare param by param as normal Strings
            for (int i = 0; i < method1.getParameters().length; i++) {
                String param1 = method1.getParameters()[i];
                String param2 = method2.getParameters()[i];
                
                int comparedValue = param1.compareTo(param2);
                if (comparedValue != 0) {
                    return comparedValue;
                }
            }
            // This should happened only if there are two absolutely identical methods
            return 0;
        }
    });
    ClassDefinition definition = loadDefinition(node);
    
    ClassNode typeNode = definition.getNode();
    String typeName = typeNode.getName();
    
    // In cases like 1.^ we have current type name "int" but indexer won't find anything for such a primitive
    if ("int".equals(typeName)) { // NOI18N
        typeName = "java.lang.Integer"; // NOI18N
    }
    context.setTypeName(typeName);

    GroovyElementsProvider groovyProvider = new GroovyElementsProvider();
    fillSuggestions(groovyProvider.getMethods(context), result);
    
    // we can't go groovy and java - helper methods would be visible
    if (result.isEmpty()) {
        String[] typeParameters = new String[(typeNode.isUsingGenerics() && typeNode.getGenericsTypes() != null)
                ? typeNode.getGenericsTypes().length : 0];
        for (int i = 0; i < typeParameters.length; i++) {
            GenericsType genType = typeNode.getGenericsTypes()[i];
            if (genType.getUpperBounds() != null) {
                typeParameters[i] = Utilities.translateClassLoaderTypeName(genType.getUpperBounds()[0].getName());
            } else {
                typeParameters[i] = Utilities.translateClassLoaderTypeName(genType.getName());
            }
        }

        fillSuggestions(JavaElementHandler.forCompilationInfo(info)
                .getMethods(typeName, prefix, anchor, typeParameters,
                        leaf, modifiedAccess, nameOnly), result);
    }

    CompletionProviderHandler providerHandler = new CompletionProviderHandler();
    fillSuggestions(providerHandler.getMethods(context), result);
    fillSuggestions(providerHandler.getStaticMethods(context), result);

    if (typeNode.getSuperClass() != null) {
        fillSuggestions(getMethodsInner(source, typeNode.getSuperClass(), prefix, anchor, level + 1, modifiedAccess, nameOnly), result);
    } else if (leaf) {
        fillSuggestions(JavaElementHandler.forCompilationInfo(info).getMethods("java.lang.Object", prefix, anchor, new String[]{}, false, modifiedAccess, nameOnly), result); // NOI18N
    }

    for (ClassNode inter : typeNode.getInterfaces()) {
        fillSuggestions(getMethodsInner(source, inter, prefix, anchor, level + 1, modifiedAccess, nameOnly), result);
    }
    
    fillSuggestions(TransformationHandler.getMethods(index, typeNode, prefix, anchor), result);
    
    return result;
}
 
Example 19
Source File: StaticTypesCallSiteWriter.java    From groovy with Apache License 2.0 4 votes vote down vote up
boolean makeGetField(final Expression receiver, final ClassNode receiverType, final String fieldName, final boolean safe, final boolean implicitThis) {
    FieldNode field = receiverType.getField(fieldName);

    if (field != null && isDirectAccessAllowed(field, controller.getClassNode())) {
        CompileStack compileStack = controller.getCompileStack();
        MethodVisitor mv = controller.getMethodVisitor();
        ClassNode replacementType = field.getOriginType();
        OperandStack operandStack = controller.getOperandStack();
        if (field.isStatic()) {
            mv.visitFieldInsn(GETSTATIC, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType));
            operandStack.push(replacementType);
        } else {
            if (implicitThis) {
                compileStack.pushImplicitThis(implicitThis);
                receiver.visit(controller.getAcg());
                compileStack.popImplicitThis();
            } else {
                receiver.visit(controller.getAcg());
            }
            Label exit = new Label();
            if (safe) {
                mv.visitInsn(DUP);
                Label doGet = new Label();
                mv.visitJumpInsn(IFNONNULL, doGet);
                mv.visitInsn(POP);
                mv.visitInsn(ACONST_NULL);
                mv.visitJumpInsn(GOTO, exit);
                mv.visitLabel(doGet);
            }
            if (!operandStack.getTopOperand().isDerivedFrom(field.getOwner())) {
                mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(field.getOwner()));
            }
            mv.visitFieldInsn(GETFIELD, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType));
            if (safe) {
                if (ClassHelper.isPrimitiveType(replacementType)) {
                    operandStack.replace(replacementType);
                    operandStack.box();
                    replacementType = operandStack.getTopOperand();
                }
                mv.visitLabel(exit);
            }
        }
        operandStack.replace(replacementType);
        return true;
    }

    for (ClassNode face : receiverType.getInterfaces()) {
        // GROOVY-7039
        if (face != receiverType && makeGetField(receiver, face, fieldName, safe, implicitThis)) {
            return true;
        }
    }

    ClassNode superClass = receiverType.getSuperClass();
    if (superClass != null && !OBJECT_TYPE.equals(superClass)) {
        return makeGetField(receiver, superClass, fieldName, safe, implicitThis);
    }
    return false;
}