1package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
2
3import com.github.javaparser.ast.expr.MethodReferenceExpr;
4import com.github.javaparser.resolution.types.ResolvedType;
5import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
6import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
7
8/**
9 * The checked exceptions thrown by the referenced method are declared by the throws clause of the function type
10 * derived from T.
11 *
12 * @author Federico Tomassetti
13 */
14public class MethodReferenceThrowsCompatibleWithType extends ConstraintFormula {
15    private MethodReferenceExpr methodReference;
16    private ResolvedType T;
17
18    @Override
19    public ReductionResult reduce(BoundSet currentBoundSet) {
20        // A constraint formula of the form ‹MethodReference →throws T› is reduced as follows:
21        //
22        // - If T is not a functional interface type, or if T is a functional interface type but does not have a function type (§9.9), the constraint reduces to false.
23        //
24        // - Otherwise, let the target function type for the method reference expression be the function type of T. If the method reference is inexact (§15.13.1) and one or more of the function type's parameter types is not a proper type, the constraint reduces to false.
25        //
26        // - Otherwise, if the method reference is inexact and the function type's result is neither void nor a proper type, the constraint reduces to false.
27        //
28        // - Otherwise, let E1, ..., En be the types in the function type's throws clause that are not proper types. Let X1, ..., Xm be the checked exceptions in the throws clause of the invocation type of the method reference's compile-time declaration (§15.13.2) (as derived from the function type's parameter types and return type). Then there are two cases:
29        //
30        //   - If n = 0 (the function type's throws clause consists only of proper types), then if there exists some i (1 ≤ i ≤ m) such that Xi is not a subtype of any proper type in the throws clause, the constraint reduces to false; otherwise, the constraint reduces to true.
31        //
32        //   - If n > 0, the constraint reduces to a set of subtyping constraints: for all i (1 ≤ i ≤ m), if Xi is not a subtype of any proper type in the throws clause, then the constraints include, for all j (1 ≤ j ≤ n), ‹Xi <: Ej›. In addition, for all j (1 ≤ j ≤ n), the constraint reduces to the bound throws Ej.
33
34        throw new UnsupportedOperationException();
35    }
36
37    @Override
38    public boolean equals(Object o) {
39        if (this == o) return true;
40        if (o == null || getClass() != o.getClass()) return false;
41
42        MethodReferenceThrowsCompatibleWithType that = (MethodReferenceThrowsCompatibleWithType) o;
43
44        if (!methodReference.equals(that.methodReference)) return false;
45        return T.equals(that.T);
46    }
47
48    @Override
49    public int hashCode() {
50        int result = methodReference.hashCode();
51        result = 31 * result + T.hashCode();
52        return result;
53    }
54
55    @Override
56    public String toString() {
57        return "MethodReferenceThrowsCompatibleWithType{" +
58                "methodReference=" + methodReference +
59                ", T=" + T +
60                '}';
61    }
62}
63