| package org.checkerframework.framework.util.typeinference.constraint; |
| |
| import java.util.Set; |
| import org.checkerframework.framework.type.AnnotatedTypeFactory; |
| import org.checkerframework.framework.type.AnnotatedTypeMirror; |
| |
| /** |
| * F2AReducer takes an F2A constraint that is not irreducible (@see AFConstraint.isIrreducible) and |
| * reduces it by one step. The resulting constraint may still be reducible. |
| * |
| * <p>Generally reductions should map to corresponding rules in |
| * https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.2.7 |
| */ |
| public class F2AReducer implements AFReducer { |
| |
| protected final F2AReducingVisitor visitor; |
| |
| public F2AReducer(final AnnotatedTypeFactory typeFactory) { |
| this.visitor = new F2AReducingVisitor(typeFactory); |
| } |
| |
| @Override |
| public boolean reduce(AFConstraint constraint, Set<AFConstraint> newConstraints) { |
| if (constraint instanceof F2A) { |
| final F2A f2A = (F2A) constraint; |
| visitor.visit(f2A.formalParameter, f2A.argument, newConstraints); |
| return true; |
| |
| } else { |
| return false; |
| } |
| } |
| |
| /** |
| * Given an F2A constraint of the form: F2A( typeFromFormalParameter, typeFromMethodArgument ) |
| * |
| * <p>F2AReducingVisitor visits the constraint as follows: visit ( typeFromFormalParameter, |
| * typeFromMethodArgument, newConstraints ) |
| * |
| * <p>The visit method will determine if the given constraint should either: |
| * |
| * <ul> |
| * <li>be discarded -- in this case, the visitor just returns |
| * <li>reduced to a simpler constraint or set of constraints -- in this case, the new constraint |
| * or set of constraints is added to newConstraints |
| * </ul> |
| * |
| * Sprinkled throughout this class are comments of the form: |
| * |
| * <pre>{@code |
| * // If F has the form G<..., Yk-1, ? super U, Yk+1, ...>, where U involves Tj |
| * }</pre> |
| * |
| * These are excerpts from the JLS, if you search for them you will find the corresponding JLS |
| * description of the case being covered. |
| */ |
| private static class F2AReducingVisitor extends AFReducingVisitor { |
| |
| public F2AReducingVisitor(AnnotatedTypeFactory typeFactory) { |
| super(F2A.class, typeFactory); |
| } |
| |
| @Override |
| public AFConstraint makeConstraint(AnnotatedTypeMirror subtype, AnnotatedTypeMirror supertype) { |
| return new F2A(subtype, supertype); |
| } |
| |
| @Override |
| public AFConstraint makeInverseConstraint( |
| AnnotatedTypeMirror subtype, AnnotatedTypeMirror supertype) { |
| return new A2F(subtype, supertype); |
| } |
| |
| @Override |
| public AFConstraint makeEqualityConstraint( |
| AnnotatedTypeMirror subtype, AnnotatedTypeMirror supertype) { |
| return new FIsA(subtype, supertype); |
| } |
| } |
| } |