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

org.checkerframework.framework.type.SubtypeVisitHistory 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.43.0
Show newest version
package org.checkerframework.framework.type;

import java.util.HashMap;
import java.util.Map;
import javax.lang.model.element.AnnotationMirror;
import org.checkerframework.javacutil.AnnotationMirrorSet;
import org.plumelib.util.IPair;

/**
 * THIS CLASS IS DESIGNED FOR USE WITH DefaultTypeHierarchy, DefaultRawnessComparer, and
 * StructuralEqualityComparer ONLY.
 *
 * 

VisitHistory tracks triples of (type1, type2, top), where type1 is a subtype of type2. It does * not track when type1 is not a subtype of type2; such entries are missing from the history. * Clients of this class can check whether or not they have visited an equivalent pair of * AnnotatedTypeMirrors already. This is necessary in order to halt visiting on recursive bounds. * *

This class is primarily used to implement isSubtype(ATM, ATM). The pair of types corresponds * to the subtype and the supertype being checked. A single subtype may be visited more than once, * but with a different supertype. For example, if the two types are {@code @A T extends @B * Serializable} and {@code @C Serializable}, then isSubtype is first called one those types * and then on {@code @B Serializable} and {@code @C Serializable}. */ // TODO: do we need to clear the history sometimes? public class SubtypeVisitHistory { /** * The keys are pairs of types; the value is the set of qualifier hierarchy roots for which the * key is in a subtype relationship. */ private final Map, AnnotationMirrorSet> visited; /** Creates a new SubtypeVisitHistory. */ public SubtypeVisitHistory() { this.visited = new HashMap<>(); } /** * Put a visit for {@code type1}, {@code type2}, and {@code top} in the history. Has no effect if * isSubtype is false. * * @param type1 the first type * @param type2 the second type * @param currentTop the top of the relevant type hierarchy; only annotations from that hierarchy * are considered * @param isSubtype whether {@code type1} is a subtype of {@code type2}; if false, this method * does nothing */ public void put( AnnotatedTypeMirror type1, AnnotatedTypeMirror type2, AnnotationMirror currentTop, boolean isSubtype) { if (!isSubtype) { // Only store information about subtype relations that hold. return; } IPair key = IPair.of(type1, type2); AnnotationMirrorSet hit = visited.get(key); if (hit != null) { hit.add(currentTop); } else { hit = new AnnotationMirrorSet(); hit.add(currentTop); this.visited.put(key, hit); } } /** Remove {@code type1} and {@code type2}. */ public void remove( AnnotatedTypeMirror type1, AnnotatedTypeMirror type2, AnnotationMirror currentTop) { IPair key = IPair.of(type1, type2); AnnotationMirrorSet hit = visited.get(key); if (hit != null) { hit.remove(currentTop); if (hit.isEmpty()) { visited.remove(key); } } } /** * Returns true if type1 and type2 (or an equivalent pair) have been passed to the put method * previously. * * @return true if an equivalent pair has already been added to the history */ public boolean contains( AnnotatedTypeMirror type1, AnnotatedTypeMirror type2, AnnotationMirror currentTop) { IPair key = IPair.of(type1, type2); AnnotationMirrorSet hit = visited.get(key); return hit != null && hit.contains(currentTop); } @Override public String toString() { return "VisitHistory( " + visited + " )"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy