All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.checkerframework.framework.type.visitor.DoubleAnnotatedTypeScanner Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java's type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.44.0
Show newest version
package org.checkerframework.framework.type.visitor;

import java.util.Iterator;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedUnionType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType;
import org.checkerframework.javacutil.BugInCF;

/**
 * An {@link AnnotatedTypeScanner} that scans two {@link AnnotatedTypeMirror}s simultaneously and
 * performs {@link #defaultAction(AnnotatedTypeMirror, AnnotatedTypeMirror)} on the pair. Both
 * AnnotatedTypeMirrors must have the same structure, or a subclass must arrange not to continue
 * recursing past the point at which their structure diverges.
 *
 * 

If the default action does not return a result, then {@code R} should be {@link Void} and * {@code DoubleAnnotatedTypeScanner()} should be used to construct the scanner. If the default * action returns a result, then specify a {@link #reduce} function and use {@code * DoubleAnnotatedTypeScanner(Reduce, Object)}. * * @see AnnotatedTypeScanner * @param the result of scanning the two {@code AnnotatedTypeMirror}s */ public abstract class DoubleAnnotatedTypeScanner extends AnnotatedTypeScanner { /** * Constructs an AnnotatedTypeScanner where the reduce function returns the first result if it is * nonnull; otherwise the second result is returned. The default result is {@code null}. */ protected DoubleAnnotatedTypeScanner() { super(); } /** * Creates a scanner with the given {@code reduce} function and {@code defaultResult}. * * @param reduce function used to combine the results of scan * @param defaultResult result to use by default */ protected DoubleAnnotatedTypeScanner(Reduce reduce, R defaultResult) { super(reduce, defaultResult); } /** * Called by default for any visit method that is not overridden. * * @param type the type to visit * @param p a visitor-specified parameter * @return a visitor-specified result */ protected abstract R defaultAction(AnnotatedTypeMirror type, AnnotatedTypeMirror p); /** * Scans {@code types1} and {@code types2}. If they are empty, then {@link #defaultResult} is * returned. * * @param types1 types * @param types2 types * @return the result of scanning and reducing all the types in {@code types1} and {@code types2} * or {@link #defaultResult} if they are empty */ protected R scan( Iterable types1, Iterable types2) { if (types1 == null || types2 == null) { return defaultResult; } R r = defaultResult; boolean first = true; Iterator iter1 = types1.iterator(); Iterator iter2 = types2.iterator(); while (iter1.hasNext() && iter2.hasNext()) { r = (first ? scan(iter1.next(), iter2.next()) : scanAndReduce(iter1.next(), iter2.next(), r)); first = false; } return r; } /** * Run {@link #scan} on types and p, then run {@link #reduce} on the result (plus r) to return a * single element. */ protected R scanAndReduce( Iterable types, Iterable p, R r) { return reduce(scan(types, p), r); } @Override protected final R scanAndReduce( Iterable types, AnnotatedTypeMirror p, R r) { throw new BugInCF( "DoubleAnnotatedTypeScanner.scanAndReduce: " + p + " is not Iterable"); } @Override protected R scan(AnnotatedTypeMirror type, AnnotatedTypeMirror p) { return reduce(super.scan(type, p), defaultAction(type, p)); } @Override public final R visitDeclared(AnnotatedDeclaredType type, AnnotatedTypeMirror p) { assert p instanceof AnnotatedDeclaredType : p; R r = scan(type.getTypeArguments(), ((AnnotatedDeclaredType) p).getTypeArguments()); if (type.getEnclosingType() != null) { r = scanAndReduce(type.getEnclosingType(), ((AnnotatedDeclaredType) p).getEnclosingType(), r); } return r; } @Override public final R visitArray(AnnotatedArrayType type, AnnotatedTypeMirror p) { assert p instanceof AnnotatedArrayType : p; R r = scan(type.getComponentType(), ((AnnotatedArrayType) p).getComponentType()); return r; } @Override public final R visitExecutable(AnnotatedExecutableType type, AnnotatedTypeMirror p) { assert p instanceof AnnotatedExecutableType : p; AnnotatedExecutableType ex = (AnnotatedExecutableType) p; R r = scan(type.getReturnType(), ex.getReturnType()); if (type.getReceiverType() != null) { r = scanAndReduce(type.getReceiverType(), ex.getReceiverType(), r); } r = scanAndReduce(type.getParameterTypes(), ex.getParameterTypes(), r); r = scanAndReduce(type.getThrownTypes(), ex.getThrownTypes(), r); r = scanAndReduce(type.getTypeVariables(), ex.getTypeVariables(), r); return r; } @Override public R visitTypeVariable(AnnotatedTypeVariable type, AnnotatedTypeMirror p) { if (visitedNodes.containsKey(type)) { return visitedNodes.get(type); } visitedNodes.put(type, null); R r; if (p instanceof AnnotatedTypeVariable) { AnnotatedTypeVariable tv = (AnnotatedTypeVariable) p; r = scan(type.getLowerBound(), tv.getLowerBound()); visitedNodes.put(type, r); r = scanAndReduce(type.getUpperBound(), tv.getUpperBound(), r); visitedNodes.put(type, r); } else { r = scan(type.getLowerBound(), p.getErased()); visitedNodes.put(type, r); r = scanAndReduce(type.getUpperBound(), p.getErased(), r); visitedNodes.put(type, r); } return r; } @Override public R visitWildcard(AnnotatedWildcardType type, AnnotatedTypeMirror p) { if (visitedNodes.containsKey(type)) { return visitedNodes.get(type); } visitedNodes.put(type, null); R r; if (p instanceof AnnotatedWildcardType) { AnnotatedWildcardType w = (AnnotatedWildcardType) p; r = scan(type.getExtendsBound(), w.getExtendsBound()); visitedNodes.put(type, r); r = scanAndReduce(type.getSuperBound(), w.getSuperBound(), r); visitedNodes.put(type, r); } else { r = scan(type.getExtendsBound(), p.getErased()); visitedNodes.put(type, r); r = scanAndReduce(type.getSuperBound(), p.getErased(), r); visitedNodes.put(type, r); } return r; } @Override public R visitIntersection(AnnotatedIntersectionType type, AnnotatedTypeMirror p) { assert p instanceof AnnotatedIntersectionType : p; if (visitedNodes.containsKey(type)) { return visitedNodes.get(type); } visitedNodes.put(type, null); R r = scan(type.getBounds(), ((AnnotatedIntersectionType) p).getBounds()); return r; } @Override public R visitUnion(AnnotatedUnionType type, AnnotatedTypeMirror p) { assert p instanceof AnnotatedUnionType : p; if (visitedNodes.containsKey(type)) { return visitedNodes.get(type); } visitedNodes.put(type, null); R r = scan(type.getAlternatives(), ((AnnotatedUnionType) p).getAlternatives()); return r; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy