Search in sources :

Example 1 with SwitchExpression

use of org.eclipse.jdt.internal.compiler.ast.SwitchExpression in project bazel-jdt-java-toolchain by salesforce.

the class ConstraintExpressionFormula method inputVariables.

@Override
Collection<InferenceVariable> inputVariables(final InferenceContext18 context) {
    // from 18.5.2.
    if (this.left instanceof LambdaExpression) {
        if (this.right instanceof InferenceVariable) {
            return Collections.singletonList((InferenceVariable) this.right);
        }
        if (this.right.isFunctionalInterface(context.scope)) {
            LambdaExpression lambda = (LambdaExpression) this.left;
            ReferenceBinding targetType = (ReferenceBinding) this.right;
            ParameterizedTypeBinding withWildCards = InferenceContext18.parameterizedWithWildcard(targetType);
            if (withWildCards != null) {
                targetType = ConstraintExpressionFormula.findGroundTargetType(context, lambda.enclosingScope, lambda, withWildCards);
            }
            if (targetType == null) {
                return EMPTY_VARIABLE_LIST;
            }
            MethodBinding sam = targetType.getSingleAbstractMethod(context.scope, true);
            final Set<InferenceVariable> variables = new LinkedHashSet<>();
            if (lambda.argumentsTypeElided()) {
                // i)
                int len = sam.parameters.length;
                for (int i = 0; i < len; i++) {
                    sam.parameters[i].collectInferenceVariables(variables);
                }
            }
            if (sam.returnType != TypeBinding.VOID) {
                // ii)
                final TypeBinding r = sam.returnType;
                LambdaExpression resolved = lambda.resolveExpressionExpecting(this.right, context.scope, context);
                Expression[] resultExpressions = resolved != null ? resolved.resultExpressions() : null;
                for (int i = 0, length = resultExpressions == null ? 0 : resultExpressions.length; i < length; i++) {
                    variables.addAll(new ConstraintExpressionFormula(resultExpressions[i], r, COMPATIBLE).inputVariables(context));
                }
            }
            return variables;
        }
    } else if (this.left instanceof ReferenceExpression) {
        if (this.right instanceof InferenceVariable) {
            return Collections.singletonList((InferenceVariable) this.right);
        }
        if (this.right.isFunctionalInterface(context.scope) && !this.left.isExactMethodReference()) {
            MethodBinding sam = this.right.getSingleAbstractMethod(context.scope, true);
            final Set<InferenceVariable> variables = new LinkedHashSet<>();
            int len = sam.parameters.length;
            for (int i = 0; i < len; i++) {
                sam.parameters[i].collectInferenceVariables(variables);
            }
            return variables;
        }
    } else if (this.left instanceof ConditionalExpression && this.left.isPolyExpression()) {
        ConditionalExpression expr = (ConditionalExpression) this.left;
        Set<InferenceVariable> variables = new LinkedHashSet<>();
        variables.addAll(new ConstraintExpressionFormula(expr.valueIfTrue, this.right, COMPATIBLE).inputVariables(context));
        variables.addAll(new ConstraintExpressionFormula(expr.valueIfFalse, this.right, COMPATIBLE).inputVariables(context));
        return variables;
    } else if (this.left instanceof SwitchExpression && this.left.isPolyExpression()) {
        SwitchExpression expr = (SwitchExpression) this.left;
        Set<InferenceVariable> variables = new LinkedHashSet<>();
        for (Expression re : expr.resultExpressions) {
            variables.addAll(new ConstraintExpressionFormula(re, this.right, COMPATIBLE).inputVariables(context));
        }
        return variables;
    }
    return EMPTY_VARIABLE_LIST;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression)

Example 2 with SwitchExpression

use of org.eclipse.jdt.internal.compiler.ast.SwitchExpression in project bazel-jdt-java-toolchain by salesforce.

the class ConstraintExpressionFormula method reduce.

@Override
public Object reduce(InferenceContext18 inferenceContext) throws InferenceFailureException {
    if (this.relation == POTENTIALLY_COMPATIBLE) {
        return this.left.isPotentiallyCompatibleWith(this.right, inferenceContext.scope) ? TRUE : FALSE;
    }
    // JLS 18.2.1
    if (this.right.isProperType(true)) {
        if (this.left.isCompatibleWith(this.right, inferenceContext.scope) || this.left.isBoxingCompatibleWith(this.right, inferenceContext.scope)) {
            if (this.left.resolvedType != null && this.left.resolvedType.needsUncheckedConversion(this.right)) {
                inferenceContext.usesUncheckedConversion = true;
            }
            return TRUE;
        }
        return FALSE;
    }
    if (!canBePolyExpression(this.left)) {
        TypeBinding exprType = this.left.resolvedType;
        if (exprType == null || !exprType.isValidBinding()) {
            if (this.left instanceof MessageSend && ((MessageSend) this.left).actualReceiverType instanceof InferenceVariable)
                // nothing valuable to infer from this
                return null;
            return FALSE;
        }
        return ConstraintTypeFormula.create(exprType, this.right, COMPATIBLE, this.isSoft);
    } else {
        // - parenthesized expression : these are transparent in our AST
        if (this.left instanceof Invocation) {
            Invocation invocation = (Invocation) this.left;
            MethodBinding previousMethod = invocation.binding();
            if (// can happen, e.g., if inside a copied lambda with ignored errors
            previousMethod == null)
                // -> proceed with no new constraints
                return null;
            MethodBinding method = previousMethod;
            // ignore previous (inner) inference result and do a fresh start:
            // avoid original(), since we only want to discard one level of instantiation
            // (method type variables - not class type variables)!
            method = previousMethod.shallowOriginal();
            SuspendedInferenceRecord prevInvocation = inferenceContext.enterPolyInvocation(invocation, invocation.arguments());
            // Invocation Applicability Inference: 18.5.1 & Invocation Type Inference: 18.5.2
            InferenceContext18 innerCtx = null;
            try {
                Expression[] arguments = invocation.arguments();
                TypeBinding[] argumentTypes = arguments == null ? Binding.NO_PARAMETERS : new TypeBinding[arguments.length];
                for (int i = 0; i < argumentTypes.length; i++) argumentTypes[i] = arguments[i].resolvedType;
                if (previousMethod instanceof ParameterizedGenericMethodBinding) {
                    // find the previous inner inference context to see what inference kind this invocation needs:
                    innerCtx = invocation.getInferenceContext((ParameterizedGenericMethodBinding) previousMethod);
                    if (innerCtx == null) {
                        /* No inference context -> the method was likely manufactured by Scope.findExactMethod -> assume it wasn't really poly after all.
							   -> proceed as for non-poly expressions.
							*/
                        TypeBinding exprType = this.left.resolvedType;
                        if (exprType == null || !exprType.isValidBinding())
                            return FALSE;
                        return ConstraintTypeFormula.create(exprType, this.right, COMPATIBLE, this.isSoft);
                    }
                    if (innerCtx.stepCompleted >= InferenceContext18.APPLICABILITY_INFERRED) {
                        inferenceContext.integrateInnerInferenceB2(innerCtx);
                    } else {
                        // should not reach here.
                        return FALSE;
                    }
                // b2 has been lifted, inferring poly invocation type amounts to lifting b3.
                } else {
                    inferenceContext.inferenceKind = inferenceContext.getInferenceKind(previousMethod, argumentTypes);
                    boolean isDiamond = method.isConstructor() && this.left.isPolyExpression(method);
                    inferInvocationApplicability(inferenceContext, method, argumentTypes, isDiamond, inferenceContext.inferenceKind);
                // b2 has been lifted, inferring poly invocation type amounts to lifting b3.
                }
                if (!inferenceContext.computeB3(invocation, this.right, method))
                    return FALSE;
                // already incorporated
                return null;
            } finally {
                inferenceContext.resumeSuspendedInference(prevInvocation, innerCtx);
            }
        } else if (this.left instanceof ConditionalExpression) {
            ConditionalExpression conditional = (ConditionalExpression) this.left;
            return new ConstraintFormula[] { new ConstraintExpressionFormula(conditional.valueIfTrue, this.right, this.relation, this.isSoft), new ConstraintExpressionFormula(conditional.valueIfFalse, this.right, this.relation, this.isSoft) };
        } else if (this.left instanceof SwitchExpression) {
            SwitchExpression se = (SwitchExpression) this.left;
            ConstraintFormula[] cfs = new ConstraintFormula[se.resultExpressions.size()];
            int i = 0;
            for (Expression re : se.resultExpressions) {
                cfs[i++] = new ConstraintExpressionFormula(re, this.right, this.relation, this.isSoft);
            }
            return cfs;
        } else if (this.left instanceof LambdaExpression) {
            LambdaExpression lambda = (LambdaExpression) this.left;
            BlockScope scope = lambda.enclosingScope;
            if (this.right instanceof InferenceVariable)
                // assume inner inference will handle the fine print
                return TRUE;
            if (!this.right.isFunctionalInterface(scope))
                return FALSE;
            ReferenceBinding t = (ReferenceBinding) this.right;
            ParameterizedTypeBinding withWildCards = InferenceContext18.parameterizedWithWildcard(t);
            if (withWildCards != null) {
                t = findGroundTargetType(inferenceContext, scope, lambda, withWildCards);
            }
            if (t == null)
                return FALSE;
            MethodBinding functionType = t.getSingleAbstractMethod(scope, true);
            if (functionType == null)
                return FALSE;
            TypeBinding[] parameters = functionType.parameters;
            if (parameters.length != lambda.arguments().length)
                return FALSE;
            if (lambda.argumentsTypeElided())
                for (int i = 0; i < parameters.length; i++) if (!parameters[i].isProperType(true))
                    return FALSE;
            lambda = lambda.resolveExpressionExpecting(t, inferenceContext.scope, inferenceContext);
            if (lambda == null)
                // not strictly unreduceable, but proceeding with TRUE would likely produce secondary errors
                return FALSE;
            if (functionType.returnType == TypeBinding.VOID) {
                if (!lambda.isVoidCompatible())
                    return FALSE;
            } else {
                if (!lambda.isValueCompatible())
                    return FALSE;
            }
            List<ConstraintFormula> result = new ArrayList<>();
            if (!lambda.argumentsTypeElided()) {
                Argument[] arguments = lambda.arguments();
                for (int i = 0; i < parameters.length; i++) result.add(ConstraintTypeFormula.create(parameters[i], arguments[i].type.resolvedType, SAME));
                // in addition, ⟨T' <: T⟩:
                if (lambda.resolvedType != null)
                    result.add(ConstraintTypeFormula.create(lambda.resolvedType, this.right, SUBTYPE));
            }
            if (functionType.returnType != TypeBinding.VOID) {
                TypeBinding r = functionType.returnType;
                Expression[] exprs = lambda.resultExpressions();
                for (int i = 0, length = exprs == null ? 0 : exprs.length; i < length; i++) {
                    Expression expr = exprs[i];
                    if (r.isProperType(true) && expr.resolvedType != null) {
                        TypeBinding exprType = expr.resolvedType;
                        // "not compatible in an assignment context with R"?
                        if (!(expr.isConstantValueOfTypeAssignableToType(exprType, r) || exprType.isCompatibleWith(r) || expr.isBoxingCompatible(exprType, r, expr, scope)))
                            return FALSE;
                    } else {
                        result.add(new ConstraintExpressionFormula(expr, r, COMPATIBLE, this.isSoft));
                    }
                }
            }
            if (result.size() == 0)
                return TRUE;
            return result.toArray(new ConstraintFormula[result.size()]);
        } else if (this.left instanceof ReferenceExpression) {
            return reduceReferenceExpressionCompatibility((ReferenceExpression) this.left, inferenceContext);
        }
    }
    return FALSE;
}
Also used : Invocation(org.eclipse.jdt.internal.compiler.ast.Invocation) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) ArrayList(java.util.ArrayList) List(java.util.List) SuspendedInferenceRecord(org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression)

Example 3 with SwitchExpression

use of org.eclipse.jdt.internal.compiler.ast.SwitchExpression in project bazel-jdt-java-toolchain by salesforce.

the class InferenceContext18 method addConstraintsToC_OneExpr.

private boolean addConstraintsToC_OneExpr(Expression expri, Set<ConstraintFormula> c, TypeBinding fsi, TypeBinding substF, MethodBinding method) throws InferenceFailureException {
    boolean substFIsProperType = substF.isProperType(true);
    // -- not per JLS, emulate javac behavior:
    substF = Scope.substitute(getResultSubstitution(this.b3), substF);
    // For all i (1 ≤ i ≤ k), if ei is not pertinent to applicability, the set contains ⟨ei → θ Fi⟩.
    if (!expri.isPertinentToApplicability(fsi, method)) {
        c.add(new ConstraintExpressionFormula(expri, substF, ReductionResult.COMPATIBLE, ARGUMENT_CONSTRAINTS_ARE_SOFT));
    }
    if (expri instanceof FunctionalExpression) {
        c.add(new ConstraintExceptionFormula((FunctionalExpression) expri, substF));
        if (expri instanceof LambdaExpression) {
            // https://bugs.openjdk.java.net/browse/JDK-8038747
            LambdaExpression lambda = (LambdaExpression) expri;
            BlockScope skope = lambda.enclosingScope;
            if (substF.isFunctionalInterface(skope)) {
                // could be an inference variable.
                ReferenceBinding t = (ReferenceBinding) substF;
                ParameterizedTypeBinding withWildCards = InferenceContext18.parameterizedWithWildcard(t);
                if (withWildCards != null) {
                    t = ConstraintExpressionFormula.findGroundTargetType(this, skope, lambda, withWildCards);
                }
                MethodBinding functionType;
                if (t != null && (functionType = t.getSingleAbstractMethod(skope, true)) != null && (lambda = lambda.resolveExpressionExpecting(t, this.scope, this)) != null) {
                    TypeBinding r = functionType.returnType;
                    Expression[] resultExpressions = lambda.resultExpressions();
                    for (int i = 0, length = resultExpressions == null ? 0 : resultExpressions.length; i < length; i++) {
                        Expression resultExpression = resultExpressions[i];
                        if (!addConstraintsToC_OneExpr(resultExpression, c, r.original(), r, method))
                            return false;
                    }
                }
            }
        }
    } else if (expri instanceof Invocation && expri.isPolyExpression()) {
        if (// https://bugs.openjdk.java.net/browse/JDK-8052325
        substFIsProperType)
            return true;
        Invocation invocation = (Invocation) expri;
        MethodBinding innerMethod = invocation.binding();
        if (innerMethod == null)
            // -> proceed with no new C set elements.
            return true;
        Expression[] arguments = invocation.arguments();
        TypeBinding[] argumentTypes = arguments == null ? Binding.NO_PARAMETERS : new TypeBinding[arguments.length];
        for (int i = 0; i < argumentTypes.length; i++) argumentTypes[i] = arguments[i].resolvedType;
        InferenceContext18 innerContext = null;
        if (innerMethod instanceof ParameterizedGenericMethodBinding)
            innerContext = invocation.getInferenceContext((ParameterizedGenericMethodBinding) innerMethod);
        if (innerContext != null) {
            MethodBinding shallowMethod = innerMethod.shallowOriginal();
            innerContext.outerContext = this;
            if (// shouldn't happen, but let's play safe
            innerContext.stepCompleted < InferenceContext18.APPLICABILITY_INFERRED)
                innerContext.inferInvocationApplicability(shallowMethod, argumentTypes, shallowMethod.isConstructor());
            if (!innerContext.computeB3(invocation, substF, shallowMethod))
                return false;
            if (innerContext.addConstraintsToC(arguments, c, innerMethod.genericMethod(), innerContext.inferenceKind, invocation)) {
                this.currentBounds.addBounds(innerContext.currentBounds, this.environment);
                return true;
            }
            return false;
        } else {
            int applicabilityKind = getInferenceKind(innerMethod, argumentTypes);
            return this.addConstraintsToC(arguments, c, innerMethod.genericMethod(), applicabilityKind, invocation);
        }
    } else if (expri instanceof ConditionalExpression) {
        ConditionalExpression ce = (ConditionalExpression) expri;
        return addConstraintsToC_OneExpr(ce.valueIfTrue, c, fsi, substF, method) && addConstraintsToC_OneExpr(ce.valueIfFalse, c, fsi, substF, method);
    } else if (expri instanceof SwitchExpression) {
        SwitchExpression se = (SwitchExpression) expri;
        for (Expression re : se.resultExpressions) {
            if (!addConstraintsToC_OneExpr(re, c, fsi, substF, method))
                return false;
        }
        return true;
    }
    return true;
}
Also used : Invocation(org.eclipse.jdt.internal.compiler.ast.Invocation) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) FunctionalExpression(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) FunctionalExpression(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression)

Example 4 with SwitchExpression

use of org.eclipse.jdt.internal.compiler.ast.SwitchExpression in project bazel-jdt-java-toolchain by salesforce.

the class InferenceContext18 method checkExpression.

private boolean checkExpression(Expression expri, TypeBinding[] u, TypeBinding r1, TypeBinding[] v, TypeBinding r2) throws InferenceFailureException {
    if (expri instanceof LambdaExpression && !((LambdaExpression) expri).argumentsTypeElided()) {
        for (int i = 0; i < u.length; i++) {
            if (!reduceAndIncorporate(ConstraintTypeFormula.create(u[i], v[i], ReductionResult.SAME)))
                return false;
        }
        if (r2.id == TypeIds.T_void)
            return true;
        LambdaExpression lambda = (LambdaExpression) expri;
        Expression[] results = lambda.resultExpressions();
        if (results != Expression.NO_EXPRESSIONS) {
            if (r1.isFunctionalInterface(this.scope) && r2.isFunctionalInterface(this.scope) && !(r1.isCompatibleWith(r2) || r2.isCompatibleWith(r1))) {
                // (what does "applied .. to R1 and R2" mean? Why mention R1/R2 and not U/V?)
                for (int i = 0; i < results.length; i++) {
                    if (!checkExpression(results[i], u, r1, v, r2))
                        return false;
                }
                return true;
            }
            checkPrimitive1: if (r1.isPrimitiveType() && !r2.isPrimitiveType()) {
                // check: each result expression is a standalone expression of a primitive type
                for (int i = 0; i < results.length; i++) {
                    if (results[i].isPolyExpression() || (results[i].resolvedType != null && !results[i].resolvedType.isPrimitiveType()))
                        break checkPrimitive1;
                }
                return true;
            }
            checkPrimitive2: if (r2.isPrimitiveType() && !r1.isPrimitiveType()) {
                for (int i = 0; i < results.length; i++) {
                    // for all expressions (not for any expression not)
                    if (!(// standalone of a referencetype
                    (!results[i].isPolyExpression() && (results[i].resolvedType != null && !results[i].resolvedType.isPrimitiveType())) || // or a poly
                    results[i].isPolyExpression()))
                        break checkPrimitive2;
                }
                return true;
            }
        }
        return reduceAndIncorporate(ConstraintTypeFormula.create(r1, r2, ReductionResult.SUBTYPE));
    } else if (expri instanceof ReferenceExpression && ((ReferenceExpression) expri).isExactMethodReference()) {
        ReferenceExpression reference = (ReferenceExpression) expri;
        for (int i = 0; i < u.length; i++) {
            if (!reduceAndIncorporate(ConstraintTypeFormula.create(u[i], v[i], ReductionResult.SAME)))
                return false;
        }
        if (r2.id == TypeIds.T_void)
            return true;
        MethodBinding method = reference.getExactMethod();
        TypeBinding returnType = method.isConstructor() ? method.declaringClass : method.returnType;
        if (r1.isPrimitiveType() && !r2.isPrimitiveType() && returnType.isPrimitiveType())
            return true;
        if (r2.isPrimitiveType() && !r1.isPrimitiveType() && !returnType.isPrimitiveType())
            return true;
        return reduceAndIncorporate(ConstraintTypeFormula.create(r1, r2, ReductionResult.SUBTYPE));
    } else if (expri instanceof ConditionalExpression) {
        ConditionalExpression cond = (ConditionalExpression) expri;
        return checkExpression(cond.valueIfTrue, u, r1, v, r2) && checkExpression(cond.valueIfFalse, u, r1, v, r2);
    } else if (expri instanceof SwitchExpression) {
        SwitchExpression se = (SwitchExpression) expri;
        for (Expression re : se.resultExpressions) {
            if (!checkExpression(re, u, r1, v, r2))
                return false;
        }
        return true;
    } else {
        return false;
    }
}
Also used : SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) FunctionalExpression(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression)

Example 5 with SwitchExpression

use of org.eclipse.jdt.internal.compiler.ast.SwitchExpression in project bazel-jdt-java-toolchain by salesforce.

the class ProblemReporter method expressionNonNullComparison.

/**
 * @param expr expression being compared for null or nonnull
 * @param checkForNull true if checking for null, false if checking for nonnull
 */
public boolean expressionNonNullComparison(Expression expr, boolean checkForNull) {
    int problemId = 0;
    Binding binding = null;
    String[] arguments = null;
    int start = 0, end = 0;
    Expression location = expr;
    if (expr.resolvedType != null) {
        long tagBits = expr.resolvedType.tagBits & TagBits.AnnotationNullMASK;
        if (tagBits == TagBits.AnnotationNonNull) {
            problemId = IProblem.RedundantNullCheckAgainstNonNullType;
            arguments = new String[] { String.valueOf(expr.resolvedType.nullAnnotatedReadableName(this.options, true)) };
            start = nodeSourceStart(location);
            end = nodeSourceEnd(location);
            handle(problemId, arguments, arguments, start, end);
            return true;
        }
    }
    // unwrap uninteresting nodes:
    while (true) {
        if (expr instanceof Assignment)
            // don't report against the assignment, but the variable
            return false;
        else if (expr instanceof CastExpression)
            expr = ((CastExpression) expr).expression;
        else
            break;
    }
    // check all those kinds of expressions that can possible answer NON_NULL from nullStatus():
    if (expr instanceof MessageSend) {
        problemId = checkForNull ? IProblem.NonNullMessageSendComparisonYieldsFalse : IProblem.RedundantNullCheckOnNonNullMessageSend;
        MethodBinding method = ((MessageSend) expr).binding;
        binding = method;
        arguments = new String[] { new String(method.shortReadableName()) };
        start = location.sourceStart;
        end = location.sourceEnd;
    } else if (expr instanceof Reference && !(expr instanceof ThisReference) && !(expr instanceof ArrayReference)) {
        FieldBinding field = ((Reference) expr).lastFieldBinding();
        if (field == null) {
            return false;
        }
        if (field.isNonNull()) {
            problemId = checkForNull ? IProblem.NonNullSpecdFieldComparisonYieldsFalse : IProblem.RedundantNullCheckOnNonNullSpecdField;
            char[][] nonNullName = this.options.nonNullAnnotationName;
            arguments = new String[] { new String(field.name), new String(nonNullName[nonNullName.length - 1]) };
        } else if (field.constant() != Constant.NotAConstant) {
            problemId = checkForNull ? IProblem.ConstNonNullFieldComparisonYieldsFalse : IProblem.RedundantNullCheckOnConstNonNullField;
            char[][] nonNullName = this.options.nonNullAnnotationName;
            arguments = new String[] { new String(field.name), new String(nonNullName[nonNullName.length - 1]) };
        } else {
            // signaling redundancy based on syntactic analysis:
            problemId = checkForNull ? IProblem.FieldComparisonYieldsFalse : IProblem.RedundantNullCheckOnField;
            arguments = new String[] { String.valueOf(field.name) };
        }
        binding = field;
        start = nodeSourceStart(binding, location);
        end = nodeSourceEnd(binding, location);
    } else if (expr instanceof AllocationExpression || expr instanceof ArrayAllocationExpression || expr instanceof ArrayInitializer || expr instanceof ClassLiteralAccess || expr instanceof ThisReference) {
    // fall through to bottom
    } else if (expr instanceof Literal || expr instanceof ConditionalExpression || expr instanceof SwitchExpression) {
        if (expr instanceof NullLiteral) {
            // reported as nonnull??
            needImplementation(location);
            return false;
        }
        if (expr.resolvedType != null && expr.resolvedType.isBaseType()) {
            // false alarm, auto(un)boxing is involved
            return false;
        }
    // fall through to bottom
    } else if (expr instanceof BinaryExpression) {
        if ((expr.bits & ASTNode.ReturnTypeIDMASK) != TypeIds.T_JavaLangString) {
            // false alarm, primitive types involved, must be auto(un)boxing?
            return false;
        }
    // fall through to bottom
    } else {
        // want to see if we get here
        needImplementation(expr);
        return false;
    }
    if (problemId == 0) {
        // standard case, fill in details now
        problemId = checkForNull ? IProblem.NonNullExpressionComparisonYieldsFalse : IProblem.RedundantNullCheckOnNonNullExpression;
        start = location.sourceStart;
        end = location.sourceEnd;
        arguments = NoArgument;
    }
    this.handle(problemId, arguments, arguments, start, end);
    return true;
}
Also used : LocalVariableBinding(org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ArrayBinding(org.eclipse.jdt.internal.compiler.lookup.ArrayBinding) AnnotationBinding(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding) WildcardBinding(org.eclipse.jdt.internal.compiler.lookup.WildcardBinding) SyntheticArgumentBinding(org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding) Binding(org.eclipse.jdt.internal.compiler.lookup.Binding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) PackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding) RecordComponentBinding(org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding) ModuleBinding(org.eclipse.jdt.internal.compiler.lookup.ModuleBinding) ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) VariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding) SplitPackageBinding(org.eclipse.jdt.internal.compiler.lookup.SplitPackageBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) CaptureBinding(org.eclipse.jdt.internal.compiler.lookup.CaptureBinding) TypeVariableBinding(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) ArrayAllocationExpression(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) ArrayReference(org.eclipse.jdt.internal.compiler.ast.ArrayReference) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) NameReference(org.eclipse.jdt.internal.compiler.ast.NameReference) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) ArrayQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference) ArrayTypeReference(org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference) Reference(org.eclipse.jdt.internal.compiler.ast.Reference) QualifiedNameReference(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) ModuleReference(org.eclipse.jdt.internal.compiler.ast.ModuleReference) QualifiedSuperReference(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) ArrayReference(org.eclipse.jdt.internal.compiler.ast.ArrayReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) FieldReference(org.eclipse.jdt.internal.compiler.ast.FieldReference) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) ImportReference(org.eclipse.jdt.internal.compiler.ast.ImportReference) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) CompoundAssignment(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) Assignment(org.eclipse.jdt.internal.compiler.ast.Assignment) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) BinaryExpression(org.eclipse.jdt.internal.compiler.ast.BinaryExpression) BinaryExpression(org.eclipse.jdt.internal.compiler.ast.BinaryExpression) InstanceOfExpression(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression) SwitchExpression(org.eclipse.jdt.internal.compiler.ast.SwitchExpression) FunctionalExpression(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression) ReferenceExpression(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) CastExpression(org.eclipse.jdt.internal.compiler.ast.CastExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) ArrayAllocationExpression(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) QualifiedAllocationExpression(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) UnaryExpression(org.eclipse.jdt.internal.compiler.ast.UnaryExpression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) ArrayAllocationExpression(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) QualifiedAllocationExpression(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) NullLiteral(org.eclipse.jdt.internal.compiler.ast.NullLiteral) Literal(org.eclipse.jdt.internal.compiler.ast.Literal) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding) CastExpression(org.eclipse.jdt.internal.compiler.ast.CastExpression) NullLiteral(org.eclipse.jdt.internal.compiler.ast.NullLiteral) ClassLiteralAccess(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) ArrayInitializer(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer)

Aggregations

ConditionalExpression (org.eclipse.jdt.internal.compiler.ast.ConditionalExpression)5 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)5 LambdaExpression (org.eclipse.jdt.internal.compiler.ast.LambdaExpression)5 ReferenceExpression (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression)5 SwitchExpression (org.eclipse.jdt.internal.compiler.ast.SwitchExpression)5 FunctionalExpression (org.eclipse.jdt.internal.compiler.ast.FunctionalExpression)3 Invocation (org.eclipse.jdt.internal.compiler.ast.Invocation)2 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)2 ArrayList (java.util.ArrayList)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 Set (java.util.Set)1 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)1 ArrayAllocationExpression (org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression)1 ArrayInitializer (org.eclipse.jdt.internal.compiler.ast.ArrayInitializer)1 ArrayQualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference)1 ArrayReference (org.eclipse.jdt.internal.compiler.ast.ArrayReference)1 ArrayTypeReference (org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference)1 Assignment (org.eclipse.jdt.internal.compiler.ast.Assignment)1 BinaryExpression (org.eclipse.jdt.internal.compiler.ast.BinaryExpression)1