Search in sources :

Example 6 with ExecutableElement

use of javax.lang.model.element.ExecutableElement in project epoxy by airbnb.

the class HashCodeValidator method hasHashCodeInClassHierarchy.

private boolean hasHashCodeInClassHierarchy(TypeElement clazz) {
    ExecutableElement methodOnClass = getMethodOnClass(clazz, HASH_CODE_METHOD, typeUtils);
    if (methodOnClass == null) {
        return false;
    }
    Element implementingClass = methodOnClass.getEnclosingElement();
    if (implementingClass.getSimpleName().toString().equals("Object")) {
        // Don't count default implementation on Object class
        return false;
    }
    // correctly :P)
    return true;
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement)

Example 7 with ExecutableElement

use of javax.lang.model.element.ExecutableElement in project epoxy by airbnb.

the class ProcessorUtils method implementsMethod.

/**
   * @return True if the clazz (or one of its superclasses) implements the given method. Returns
   * false if the method doesn't exist anywhere in the class hierarchy or it is abstract.
   */
static boolean implementsMethod(TypeElement clazz, MethodSpec method, Types typeUtils) {
    ExecutableElement methodOnClass = getMethodOnClass(clazz, method, typeUtils);
    if (methodOnClass == null) {
        return false;
    }
    Set<Modifier> modifiers = methodOnClass.getModifiers();
    return !modifiers.contains(Modifier.ABSTRACT);
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) Modifier(javax.lang.model.element.Modifier)

Example 8 with ExecutableElement

use of javax.lang.model.element.ExecutableElement in project immutables by immutables.

the class SourceOrdering method getAllAccessorsProvider.

/**
   * While we have {@link SourceOrdering}, there's still a problem: We have inheritance hierarchy
   * and
   * we want to have all defined or inherited accessors returned as members of target type, like
   * {@link Elements#getAllMembers(TypeElement)}, but we need to have them properly and stably
   * sorted.
   * This implementation doesn't try to correctly resolve order for accessors inherited from
   * different supertypes(interfaces), just something that stable and reasonable wrt source ordering
   * without handling complex cases.
   * @param elements the elements utility
   * @param types the types utility
   * @param type the type to traverse
   * @return provider of all accessors in source order and mapping
   */
public static AccessorProvider getAllAccessorsProvider(final Elements elements, final Types types, final TypeElement type) {
    class CollectedOrdering extends Ordering<Element> {

        class Intratype {

            Ordering<String> ordering;

            int rank;
        }

        final Map<String, Intratype> accessorOrderings = Maps.newLinkedHashMap();

        final List<TypeElement> linearizedTypes = Lists.newArrayList();

        final Predicate<String> accessorNotYetInOrderings = Predicates.not(Predicates.in(accessorOrderings.keySet()));

        final ArrayListMultimap<String, TypeElement> accessorMapping = ArrayListMultimap.create();

        CollectedOrdering() {
            traverse(type);
            traverseObjectForInterface();
        }

        private void traverseObjectForInterface() {
            if (type.getKind() == ElementKind.INTERFACE) {
                traverse(elements.getTypeElement(Object.class.getName()));
            }
        }

        void traverse(@Nullable TypeElement element) {
            if (element == null || isJavaLangObject(element)) {
                return;
            }
            collectEnclosing(element);
            traverse(asTypeElement(element.getSuperclass()));
            for (TypeMirror implementedInterface : element.getInterfaces()) {
                traverse(asTypeElement(implementedInterface));
            }
        }

        @Nullable
        TypeElement asTypeElement(TypeMirror type) {
            if (type.getKind() == TypeKind.DECLARED) {
                return (TypeElement) ((DeclaredType) type).asElement();
            }
            return null;
        }

        void collectEnclosing(TypeElement type) {
            FluentIterable<String> accessorsInType = FluentIterable.from(SourceOrdering.getEnclosedElements(type)).filter(IsParameterlessNonstaticNonobject.PREDICATE).transform(ToSimpleName.FUNCTION);
            for (String accessor : accessorsInType) {
                accessorMapping.put(accessor, type);
            }
            List<String> accessors = accessorsInType.filter(accessorNotYetInOrderings).toList();
            Intratype intratype = new Intratype();
            intratype.rank = linearizedTypes.size();
            intratype.ordering = Ordering.explicit(accessors);
            for (String name : accessors) {
                accessorOrderings.put(name, intratype);
            }
            linearizedTypes.add(type);
        }

        @Override
        public int compare(Element left, Element right) {
            String leftKey = ToSimpleName.FUNCTION.apply(left);
            String rightKey = ToSimpleName.FUNCTION.apply(right);
            Intratype leftIntratype = accessorOrderings.get(leftKey);
            Intratype rightIntratype = accessorOrderings.get(rightKey);
            if (leftIntratype == null || rightIntratype == null) {
                // FIXME figure out why it happens (null)
                return Boolean.compare(leftIntratype == null, rightIntratype == null);
            }
            return leftIntratype == rightIntratype ? leftIntratype.ordering.compare(leftKey, rightKey) : Integer.compare(leftIntratype.rank, rightIntratype.rank);
        }
    }
    final CollectedOrdering ordering = new CollectedOrdering();
    final ImmutableList<ExecutableElement> sortedList = ordering.immutableSortedCopy(disambiguateMethods(ElementFilter.methodsIn(elements.getAllMembers(type))));
    return new AccessorProvider() {

        ImmutableListMultimap<String, TypeElement> accessorMapping = ImmutableListMultimap.copyOf(ordering.accessorMapping);

        @Override
        public ImmutableListMultimap<String, TypeElement> accessorMapping() {
            return accessorMapping;
        }

        @Override
        public ImmutableList<ExecutableElement> get() {
            return sortedList;
        }
    };
}
Also used : TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) Predicate(com.google.common.base.Predicate) TypeMirror(javax.lang.model.type.TypeMirror) Ordering(com.google.common.collect.Ordering) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) ArrayListMultimap(com.google.common.collect.ArrayListMultimap) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) Nullable(javax.annotation.Nullable)

Example 9 with ExecutableElement

use of javax.lang.model.element.ExecutableElement in project jOOQ by jOOQ.

the class SQLDialectChecker method createSourceVisitor.

@Override
protected SourceVisitor<Void, Void> createSourceVisitor() {
    return new SourceVisitor<Void, Void>(getChecker()) {

        @Override
        public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
            try {
                ExecutableElement elementFromUse = elementFromUse(node);
                Support support = elementFromUse.getAnnotation(Support.class);
                // all jOOQ API method calls will type check.
                if (support != null && support.value().length > 0) {
                    Element enclosing = elementFromDeclaration(enclosingMethod(getPath(root, node)));
                    EnumSet<SQLDialect> supported = EnumSet.copyOf(asList(support.value()));
                    EnumSet<SQLDialect> allowed = EnumSet.noneOf(SQLDialect.class);
                    EnumSet<SQLDialect> required = EnumSet.noneOf(SQLDialect.class);
                    boolean evaluateRequire = true;
                    while (enclosing != null) {
                        Allow allow = enclosing.getAnnotation(Allow.class);
                        if (allow != null)
                            allowed.addAll(asList(allow.value()));
                        if (evaluateRequire) {
                            Require require = enclosing.getAnnotation(Require.class);
                            if (require != null) {
                                evaluateRequire = false;
                                required.clear();
                                required.addAll(asList(require.value()));
                            }
                        }
                        enclosing = enclosing.getEnclosingElement();
                    }
                    if (allowed.isEmpty())
                        error(node, "No jOOQ API usage is allowed at current scope. Use @Allow.");
                    if (required.isEmpty())
                        error(node, "No jOOQ API usage is allowed at current scope due to conflicting @Require specification.");
                    boolean allowedFail = true;
                    allowedLoop: for (SQLDialect a : allowed) {
                        for (SQLDialect s : supported) {
                            if (a.supports(s)) {
                                allowedFail = false;
                                break allowedLoop;
                            }
                        }
                    }
                    if (allowedFail)
                        error(node, "The allowed dialects in scope " + allowed + " do not include any of the supported dialects: " + supported);
                    boolean requiredFail = false;
                    requiredLoop: for (SQLDialect r : required) {
                        for (SQLDialect s : supported) if (r.supports(s))
                            continue requiredLoop;
                        requiredFail = true;
                        break requiredLoop;
                    }
                    if (requiredFail)
                        error(node, "Not all of the required dialects " + required + " from the current scope are supported " + supported);
                }
            } catch (final Exception e) {
                print(new Printer() {

                    @Override
                    public void print(PrintWriter t) {
                        e.printStackTrace(t);
                    }
                });
            }
            return super.visitMethodInvocation(node, p);
        }
    };
}
Also used : Require(org.jooq.Require) Support(org.jooq.Support) SourceVisitor(org.checkerframework.framework.source.SourceVisitor) ExecutableElement(javax.lang.model.element.ExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) Allow(org.jooq.Allow) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) SQLDialect(org.jooq.SQLDialect) PrintWriter(java.io.PrintWriter)

Example 10 with ExecutableElement

use of javax.lang.model.element.ExecutableElement in project jOOQ by jOOQ.

the class PlainSQLChecker method createSourceVisitor.

@Override
protected SourceVisitor<Void, Void> createSourceVisitor() {
    return new SourceVisitor<Void, Void>(getChecker()) {

        @Override
        public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
            try {
                ExecutableElement elementFromUse = elementFromUse(node);
                PlainSQL plainSQL = elementFromUse.getAnnotation(PlainSQL.class);
                // all jOOQ API method calls will type check.
                if (plainSQL != null) {
                    Element enclosing = elementFromDeclaration(enclosingMethod(getPath(root, node)));
                    boolean allowed = false;
                    moveUpEnclosingLoop: while (enclosing != null) {
                        if (enclosing.getAnnotation(Allow.PlainSQL.class) != null) {
                            allowed = true;
                            break moveUpEnclosingLoop;
                        }
                        enclosing = enclosing.getEnclosingElement();
                    }
                    if (!allowed)
                        error(node, "Plain SQL usage not allowed at current scope. Use @Allow.PlainSQL.");
                }
            } catch (final Exception e) {
                print(new Printer() {

                    @Override
                    public void print(PrintWriter t) {
                        e.printStackTrace(t);
                    }
                });
            }
            return super.visitMethodInvocation(node, p);
        }
    };
}
Also used : MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) SourceVisitor(org.checkerframework.framework.source.SourceVisitor) ExecutableElement(javax.lang.model.element.ExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) PlainSQL(org.jooq.PlainSQL) Allow(org.jooq.Allow) PrintWriter(java.io.PrintWriter)

Aggregations

ExecutableElement (javax.lang.model.element.ExecutableElement)341 TypeElement (javax.lang.model.element.TypeElement)154 TypeMirror (javax.lang.model.type.TypeMirror)96 VariableElement (javax.lang.model.element.VariableElement)85 Element (javax.lang.model.element.Element)69 Test (org.junit.Test)41 GeneratedExecutableElement (com.google.devtools.j2objc.types.GeneratedExecutableElement)32 DeclaredType (javax.lang.model.type.DeclaredType)30 ArrayList (java.util.ArrayList)26 JBlock (com.helger.jcodemodel.JBlock)25 JInvocation (com.helger.jcodemodel.JInvocation)20 MethodDeclaration (com.google.devtools.j2objc.ast.MethodDeclaration)18 JVar (com.helger.jcodemodel.JVar)18 Map (java.util.Map)18 IJExpression (com.helger.jcodemodel.IJExpression)16 HashSet (java.util.HashSet)16 ElementValidation (org.androidannotations.ElementValidation)15 Block (com.google.devtools.j2objc.ast.Block)13 JMethod (com.helger.jcodemodel.JMethod)13 FunctionInvocation (com.google.devtools.j2objc.ast.FunctionInvocation)11