@Override public boolean visitIfExpression(@NotNull UIfExpression node) { UExpression condition = node.getCondition(); UExpression body = node.getThenBranch(); UElement elseBody = node.getElseBranch(); condition.accept(this); if (body != null) { boolean wasReachable = mReachable; body.accept(this); mReachable = wasReachable; } if (elseBody != null) { boolean wasReachable = mReachable; elseBody.accept(this); mReachable = wasReachable; } return false; }
private static int calculateValue(UastAndroidContext context, UExpression expression) { // This function assumes that the only inputs to the expression are static integer // flags that combined via bitwise operands. if (UastLiteralUtils.isIntegralLiteral(expression)) { return (int) UastLiteralUtils.getLongValue((ULiteralExpression) expression); } if (expression instanceof UResolvable) { UDeclaration resolvedNode = ((UResolvable) expression).resolve(context); if (resolvedNode instanceof UVariable) { UExpression initializer = ((UVariable) resolvedNode).getInitializer(); if (initializer != null) { Object value = initializer.evaluate(); if (value instanceof Integer) { return (Integer) value; } } } } if (expression instanceof UBinaryExpression) { UBinaryExpression binaryExpression = (UBinaryExpression) expression; UastBinaryOperator operator = binaryExpression.getOperator(); int leftValue = calculateValue(context, binaryExpression.getLeftOperand()); int rightValue = calculateValue(context, binaryExpression.getRightOperand()); if (operator == UastBinaryOperator.BITWISE_OR) { return leftValue | rightValue; } if (operator == UastBinaryOperator.BITWISE_AND) { return leftValue & rightValue; } if (operator == UastBinaryOperator.BITWISE_XOR) { return leftValue ^ rightValue; } } return 0; }
@Override public void visitCall(UastAndroidContext context, UCallExpression node) { String lhs = getLhs(node); if (lhs == null) { return; } UFunction method = UastUtils.getContainingFunction(node); if (method == null) { return; } else if (method != mLastMethod) { mIds = Maps.newHashMap(); mLhs = Maps.newHashMap(); mCallOperands = Maps.newHashMap(); mLastMethod = method; } UElement parent = node.getParent(); String callOperand = ""; if (parent instanceof UQualifiedExpression) { callOperand = ((UQualifiedExpression) parent).getReceiver().renderString(); } UExpression first = node.getValueArguments().get(0); if (first instanceof UQualifiedExpression) { UQualifiedExpression select = (UQualifiedExpression) first; String id = select.getSelector().renderString(); UExpression operand = select.getReceiver(); if (operand instanceof UQualifiedExpression) { UQualifiedExpression type = (UQualifiedExpression) operand; if (type.getSelector().renderString().equals(RESOURCE_CLZ_ID)) { if (mIds.containsKey(id)) { if (lhs.equals(mLhs.get(id))) { return; } if (!callOperand.equals(mCallOperands.get(id))) { return; } UCallExpression earlierCall = mIds.get(id); if (!isReachableFrom(method, earlierCall, node)) { return; } Location location = context.getLocation(node); Location secondary = context.getLocation(earlierCall); if (location != null && secondary != null) { secondary.setMessage("First usage here"); location.setSecondary(secondary); context.report( ISSUE, node, location, String.format( "The id `%1$s` has already been looked up in this method; possible " + "cut & paste error?", first.toString())); } } else { mIds.put(id, node); mLhs.put(id, lhs); mCallOperands.put(id, callOperand); } } } } }