private static void checkResult(@NonNull JavaContext context, @NonNull MethodInvocation node, @NonNull ResolvedAnnotation annotation) { if (node.getParent() instanceof ExpressionStatement) { String methodName = node.astName().astValue(); 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.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); } }
Node p = node.getParent(); while (p != null) { if (p instanceof If || p instanceof InlineIfExpression
@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; }
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; }
@Override public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor, @NonNull MethodInvocation node) { if (node.getParent() instanceof Cast) { Cast cast = (Cast) node.getParent(); StrictListAccessor<Expression, MethodInvocation> args = node.astArguments(); if (args.size() == 1) { String name = stripPackage(args.first().toString()); String expectedClass = getExpectedType(name); if (expectedClass != null) { String castType = cast.astTypeReference().getTypeName(); if (castType.indexOf('.') == -1) { expectedClass = stripPackage(expectedClass); } if (!castType.equals(expectedClass)) { // It's okay to mix and match // android.content.ClipboardManager and android.text.ClipboardManager if (isClipboard(castType) && isClipboard(expectedClass)) { return; } String message = String.format( "Suspicious cast to `%1$s` for a `%2$s`: expected `%3$s`", stripPackage(castType), name, stripPackage(expectedClass)); context.report(ISSUE, node, context.getLocation(cast), message); } } } } }
checkWithinConditional(context, node.getParent(), node);
@Override public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor, @NonNull MethodInvocation node) { if (node.getParent() instanceof ExpressionStatement) { if (!context.isContextMethod(node)) { return;
Node method = JavaContext.findSurroundingMethod(node.getParent()); if (method == null) { return;
JavaParser.ResolvedVariable boundVariable = getVariable(context, node); if (boundVariable == null) { Node parent = node.getParent(); while (parent instanceof MethodInvocation) { MethodInvocation methodInvocation = (MethodInvocation) parent;
Node parent = node.getParent();
Node parent = node.getParent(); boolean returnValueIgnored = false; if (parent instanceof MethodDeclaration ||