Java Code Examples for lombok.ast.Node#getParent()

The following examples show how to use lombok.ast.Node#getParent() . 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: JavaContext.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Returns the first ancestor node of the given type
 *
 * @param element the element to search from
 * @param clz     the target node type
 * @param strict  if true, do not consider the element itself, only its parents
 * @param <T>     the target node type
 * @return the nearest ancestor node in the parent chain, or null if not found
 */
@Nullable
public static <T extends Node> T getParentOfType(
        @Nullable Node element,
        @NonNull Class<T> clz,
        boolean strict) {
    if (element == null) {
        return null;
    }

    if (strict) {
        element = element.getParent();
    }

    while (element != null) {
        if (clz.isInstance(element)) {
            //noinspection unchecked
            return (T) element;
        }
        element = element.getParent();
    }

    return null;
}
 
Example 2
Source File: JavaContext.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Returns the first ancestor node of the given type, stopping at the given type
 *
 * @param element     the element to search from
 * @param clz         the target node type
 * @param strict      if true, do not consider the element itself, only its parents
 * @param terminators optional node types to terminate the search at
 * @param <T>         the target node type
 * @return the nearest ancestor node in the parent chain, or null if not found
 */
@Nullable
public static <T extends Node> T getParentOfType(@Nullable Node element,
        @NonNull Class<T> clz,
        boolean strict,
        @NonNull Class<? extends Node>... terminators) {
    if (element == null) {
        return null;
    }
    if (strict) {
        element = element.getParent();
    }

    while (element != null && !clz.isInstance(element)) {
        for (Class<?> terminator : terminators) {
            if (terminator.isInstance(element)) {
                return null;
            }
        }
        element = element.getParent();
    }

    //noinspection unchecked
    return (T) element;
}
 
Example 3
Source File: CleanupDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static boolean isCommittedInChainedCalls(@NonNull JavaContext context,
        @NonNull MethodInvocation node) {
    // Look for chained calls since the FragmentManager methods all return "this"
    // to allow constructor chaining, e.g.
    //    getFragmentManager().beginTransaction().addToBackStack("test")
    //            .disallowAddToBackStack().hide(mFragment2).setBreadCrumbShortTitle("test")
    //            .show(mFragment2).setCustomAnimations(0, 0).commit();
    Node parent = node.getParent();
    while (parent instanceof MethodInvocation) {
        MethodInvocation methodInvocation = (MethodInvocation) parent;
        if (isTransactionCommitMethodCall(context, methodInvocation)
                || isShowFragmentMethodCall(context, methodInvocation)) {
            return true;
        }

        parent = parent.getParent();
    }

    return false;
}
 
Example 4
Source File: CutPasteDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Nullable
private static String getLhs(@NonNull MethodInvocation call) {
    Node parent = call.getParent();
    if (parent instanceof Cast) {
        parent = parent.getParent();
    }

    if (parent instanceof VariableDefinitionEntry) {
        VariableDefinitionEntry vde = (VariableDefinitionEntry) parent;
        return vde.astName().astValue();
    } else if (parent instanceof BinaryExpression) {
        BinaryExpression be = (BinaryExpression) parent;
        Expression left = be.astLeft();
        if (left instanceof VariableReference || left instanceof Select) {
            return be.astLeft().toString();
        } else if (left instanceof ArrayAccess) {
            ArrayAccess aa = (ArrayAccess) left;
            return aa.astOperand().toString();
        }
    }

    return null;
}
 
Example 5
Source File: LogDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static boolean checkWithinConditional(
        @NonNull JavaContext context,
        @Nullable Node curr,
        @NonNull MethodInvocation logCall) {
    while (curr != null) {
        if (curr instanceof If) {
            If ifNode = (If) curr;
            if (ifNode.astCondition() instanceof MethodInvocation) {
                MethodInvocation call = (MethodInvocation) ifNode.astCondition();
                if (IS_LOGGABLE.equals(call.astName().astValue())) {
                    checkTagConsistent(context, logCall, call);
                }
            }

            return true;
        } else if (curr instanceof MethodInvocation
                || curr instanceof ClassDeclaration) { // static block
            break;
        }
        curr = curr.getParent();
    }
    return false;
}
 
Example 6
Source File: SharedPrefsDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Nullable
private static VariableDefinition getLhs(@NonNull Node node) {
    while (node != null) {
        Class<? extends Node> type = node.getClass();
        // The Lombok AST uses a flat hierarchy of node type implementation classes
        // so no need to do instanceof stuff here.
        if (type == MethodDeclaration.class || type == ConstructorDeclaration.class) {
            return null;
        }
        if (type == VariableDefinition.class) {
            return (VariableDefinition) node;
        }

        node = node.getParent();
    }

    return null;
}
 
Example 7
Source File: SharedPrefsDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Nullable
private static NormalTypeBody findSurroundingTypeBody(Node scope) {
    while (scope != null) {
        Class<? extends Node> type = scope.getClass();
        // The Lombok AST uses a flat hierarchy of node type implementation classes
        // so no need to do instanceof stuff here.
        if (type == NormalTypeBody.class) {
            return (NormalTypeBody) scope;
        }

        scope = scope.getParent();
    }

    return null;
}
 
Example 8
Source File: ToastDetector.java    From MeituanLintDemo with Apache License 2.0 5 votes vote down vote up
public static Node findSurroundingMethod(Node scope) {
    while(true) {
        if(scope != null) {
            Class type = scope.getClass();
            if(type != MethodDeclaration.class && type != ConstructorDeclaration.class && !isLambdaExpression(type)) {
                scope = scope.getParent();
                continue;
            }

            return scope;
        }

        return null;
    }
}
 
Example 9
Source File: UnsafeAndroidDetector.java    From SafelyAndroid with MIT License 5 votes vote down vote up
private boolean isInsideDialogFragment(JavaContext context, MethodInvocation node) {
    Node parent = node.getParent();
    while (parent != null) {
        Object resolvedNode = context.resolve(parent);
        if (resolvedNode instanceof JavaParser.ResolvedMethod) {
            JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) resolvedNode;
            if (isDialogFragment(method.getContainingClass())) {
                return true;
            }
        }
        parent = parent.getParent();
    }
    return false;
}
 
Example 10
Source File: EcjParser.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Nullable
private static Object getNativeNode(@NonNull Node node) {
    Object nativeNode = node.getNativeNode();
    if (nativeNode != null) {
        return nativeNode;
    }

    Node parent = node.getParent();
    // The ECJ native nodes are sometimes spotty; for example, for a
    // MethodInvocation node we can have a null native node, but its
    // parent expression statement will point to the real MessageSend node
    if (parent != null) {
        nativeNode = parent.getNativeNode();
        if (nativeNode != null) {
            return nativeNode;
        }
    }

    if (node instanceof VariableDefinitionEntry) {
        node = node.getParent().getParent();
    }
    if (node instanceof VariableDeclaration) {
        VariableDeclaration declaration = (VariableDeclaration) node;
        VariableDefinition definition = declaration.astDefinition();
        if (definition != null) {
            lombok.ast.TypeReference typeReference = definition.astTypeReference();
            if (typeReference != null) {
                return typeReference.getNativeNode();
            }
        }
    }

    return null;
}
 
Example 11
Source File: JavaPerformanceDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Check whether the given invocation is done as a lazy initialization,
 * e.g. {@code if (foo == null) foo = new Foo();}.
 * <p>
 * This tries to also handle the scenario where the check is on some
 * <b>other</b> variable - e.g.
 * <pre>
 *    if (foo == null) {
 *        foo == init1();
 *        bar = new Bar();
 *    }
 * </pre>
 * or
 * <pre>
 *    if (!initialized) {
 *        initialized = true;
 *        bar = new Bar();
 *    }
 * </pre>
 */
private static boolean isLazilyInitialized(Node node) {
    Node curr = node.getParent();
    while (curr != null) {
        if (curr instanceof MethodDeclaration) {
            return false;
        } else if (curr instanceof If) {
            If ifNode = (If) curr;
            // See if the if block represents a lazy initialization:
            // compute all variable names seen in the condition
            // (e.g. for "if (foo == null || bar != foo)" the result is "foo,bar"),
            // and then compute all variables assigned to in the if body,
            // and if there is an overlap, we'll consider the whole if block
            // guarded (so lazily initialized and an allocation we won't complain
            // about.)
            List<String> assignments = new ArrayList<String>();
            AssignmentTracker visitor = new AssignmentTracker(assignments);
            ifNode.astStatement().accept(visitor);
            if (!assignments.isEmpty()) {
                List<String> references = new ArrayList<String>();
                addReferencedVariables(references, ifNode.astCondition());
                if (!references.isEmpty()) {
                    SetView<String> intersection = Sets.intersection(
                            new HashSet<String>(assignments),
                            new HashSet<String>(references));
                    return !intersection.isEmpty();
                }
            }
            return false;

        }
        curr = curr.getParent();
    }

    return false;
}
 
Example 12
Source File: JavaContext.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Nullable
public static Node findSurroundingMethod(Node scope) {
    while (scope != null) {
        Class<? extends Node> type = scope.getClass();
        // The Lombok AST uses a flat hierarchy of node type implementation classes
        // so no need to do instanceof stuff here.
        if (type == MethodDeclaration.class || type == ConstructorDeclaration.class) {
            return scope;
        }

        scope = scope.getParent();
    }

    return null;
}
 
Example 13
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private static void checkResult(@NonNull JavaContext context, @NonNull Node node,
        @NonNull ResolvedAnnotation annotation) {
    if (node.getParent() instanceof ExpressionStatement) {
        String methodName = JavaContext.getMethodName(node);
        Object suggested = annotation.getValue(ATTR_SUGGEST);

        // Failing to check permissions is a potential security issue (and had an existing
        // dedicated issue id before which people may already have configured with a
        // custom severity in their LintOptions etc) so continue to use that issue
        // (which also has category Security rather than Correctness) for these:
        Issue issue = CHECK_RESULT;
        if (methodName != null && methodName.startsWith("check")
                && methodName.contains("Permission")) {
            issue = CHECK_PERMISSION;
        }

        String message = String.format("The result of `%1$s` is not used",
                methodName);
        if (suggested != null) {
            // TODO: Resolve suggest attribute (e.g. prefix annotation class if it starts
            // with "#" etc?
            message = String.format(
                    "The result of `%1$s` is not used; did you mean to call `%2$s`?",
                    methodName, suggested.toString());
        }
        context.report(issue, node, context.getLocation(node), message);
    }
}
 
Example 14
Source File: ViewHolderDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public boolean visitMethodInvocation(MethodInvocation node) {
    if (node.astOperand() != null) {
        String methodName = node.astName().astValue();
        if (methodName.equals(INFLATE) && node.astArguments().size() >= 1) {
            // See if we're inside a conditional
            boolean insideIf = false;
            Node p = node.getParent();
            while (p != null) {
                if (p instanceof If || p instanceof InlineIfExpression
                        || p instanceof Switch) {
                    insideIf = true;
                    mHaveConditional = true;
                    break;
                } else if (p == node) {
                    break;
                }
                p = p.getParent();
            }
            if (!insideIf) {
                // Rather than reporting immediately, we only report if we didn't
                // find any conditionally executed inflate statements in the method.
                // This is because there are cases where getView method is complicated
                // and inflates not just the top level layout but also children
                // of the view, and we don't want to flag these. (To be more accurate
                // should perform flow analysis and only report unconditional inflation
                // of layouts that wind up flowing to the return value; that requires
                // more work, and this simple heuristic is good enough for nearly all test
                // cases I've come across.
                if (mNodes == null) {
                    mNodes = Lists.newArrayList();
                }
                mNodes.add(node);
            }
        }
    }

    return super.visitMethodInvocation(node);
}
 
Example 15
Source File: JavaContext.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Returns the first sibling of the given node that is of the given class
 *
 * @param sibling the sibling to search from
 * @param clz     the type to look for
 * @param <T>     the type
 * @return the first sibling of the given type, or null
 */
@Nullable
public static <T extends Node> T getNextSiblingOfType(@Nullable Node sibling,
        @NonNull Class<T> clz) {
    if (sibling == null) {
        return null;
    }
    Node parent = sibling.getParent();
    if (parent == null) {
        return null;
    }

    Iterator<Node> iterator = parent.getChildren().iterator();
    while (iterator.hasNext()) {
        if (iterator.next() == sibling) {
            break;
        }
    }

    while (iterator.hasNext()) {
        Node child = iterator.next();
        if (clz.isInstance(child)) {
            //noinspection unchecked
            return (T) child;
        }

    }

    return null;
}
 
Example 16
Source File: JavaContext.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Nullable
public static ClassDeclaration findSurroundingClass(@Nullable Node scope) {
    while (scope != null) {
        Class<? extends Node> type = scope.getClass();
        // The Lombok AST uses a flat hierarchy of node type implementation classes
        // so no need to do instanceof stuff here.
        if (type == ClassDeclaration.class) {
            return (ClassDeclaration) scope;
        }

        scope = scope.getParent();
    }

    return null;
}
 
Example 17
Source File: AnnotationDetector.java    From javaide with GNU General Public License v3.0 4 votes vote down vote up
private boolean checkId(Annotation node, String id) {
    IssueRegistry registry = mContext.getDriver().getRegistry();
    Issue issue = registry.getIssue(id);
    // Special-case the ApiDetector issue, since it does both source file analysis
    // only on field references, and class file analysis on the rest, so we allow
    // annotations outside of methods only on fields
    if (issue != null && !issue.getImplementation().getScope().contains(Scope.JAVA_FILE)
            || issue == ApiDetector.UNSUPPORTED) {
        // Ensure that this isn't a field
        Node parent = node.getParent();
        while (parent != null) {
            if (parent instanceof MethodDeclaration
                    || parent instanceof ConstructorDeclaration
                    || parent instanceof Block) {
                break;
            } else if (parent instanceof TypeBody) { // It's a field
                return true;
            } else if (issue == ApiDetector.UNSUPPORTED
                    && parent instanceof VariableDefinition) {
                VariableDefinition definition = (VariableDefinition) parent;
                for (VariableDefinitionEntry entry : definition.astVariables()) {
                    Expression initializer = entry.astInitializer();
                    if (initializer instanceof Select) {
                        return true;
                    }
                }
            }
            parent = parent.getParent();
            if (parent == null) {
                return true;
            }
        }

        // This issue doesn't have AST access: annotations are not
        // available for local variables or parameters
        Node scope = getAnnotationScope(node);
        mContext.report(INSIDE_METHOD, scope, mContext.getLocation(node), String.format(
            "The `@SuppressLint` annotation cannot be used on a local " +
            "variable with the lint check '%1$s': move out to the " +
            "surrounding method", id));
        return false;
    }

    return true;
}