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

org.checkerframework.common.value.RangeOrListOfValues 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.42.0
Show newest version
package org.checkerframework.common.value;

import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import org.checkerframework.common.value.qual.ArrayLen;
import org.checkerframework.common.value.qual.ArrayLenRange;
import org.checkerframework.common.value.qual.IntVal;
import org.checkerframework.common.value.util.Range;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.javacutil.PluginUtil;

/**
 * An abstraction that can be either a range or a list of values that could come from an {@link
 * ArrayLen} or {@link IntVal}. This abstraction reduces the number of cases that {@link
 * org.checkerframework.common.value.ValueAnnotatedTypeFactory.ValueTreeAnnotator#handleInitializers(List,
 * AnnotatedTypeMirror.AnnotatedArrayType)} and {@link
 * org.checkerframework.common.value.ValueAnnotatedTypeFactory.ValueTreeAnnotator#handleDimensions(List,
 * AnnotatedTypeMirror.AnnotatedArrayType)} must handle.
 *
 * 

Tracks Ints in the list, and creates ArrayLen or ArrayLenRange annotations, because it's meant * to be used to reason about ArrayLen and ArrayLenRange values. */ class RangeOrListOfValues { private Range range; private List values; private boolean isRange; public RangeOrListOfValues(List values) { this.values = new ArrayList<>(); isRange = false; addAll(values); } public RangeOrListOfValues(Range range) { this.range = range; isRange = true; } public void add(Range otherRange) { if (isRange) { range = range.union(otherRange); } else { convertToRange(); add(otherRange); } } /** * If this is not a range, adds all members of newValues to the list. Otherwise, extends the * range as appropriate based on the max and min of newValues. If adding newValues to a * non-range would cause the list to become too large, converts this into a range. * *

If reading from an {@link org.checkerframework.common.value.qual.IntRange} annotation, * {@link #convertLongsToInts(List)} should be called before calling this method. * * @param newValues values to add */ public void addAll(List newValues) { if (isRange) { range = range.union(Range.create(newValues)); } else { for (Integer i : newValues) { if (!values.contains(i)) { values.add(i); } } if (values.size() > ValueAnnotatedTypeFactory.MAX_VALUES) { convertToRange(); } } } /** * Produces the most precise annotation that captures the information stored in this * RangeOrListofValues. The result is either a {@link ArrayLen} or a {@link ArrayLenRange}. */ public AnnotationMirror createAnnotation(ValueAnnotatedTypeFactory atypefactory) { if (isRange) { return atypefactory.createArrayLenRangeAnnotation(range); } else { return atypefactory.createArrayLenAnnotation(values); } } /** * To be called before addAll. Converts Longs to Ints; meant to be used with ArrayLenRange * (which only handles Ints). */ public static List convertLongsToInts(List newValues) { List result = new ArrayList<>(newValues.size()); for (Long l : newValues) { if (l > Integer.MAX_VALUE) { result.add(Integer.MAX_VALUE); } else if (l < Integer.MIN_VALUE) { result.add(Integer.MIN_VALUE); } else { result.add(l.intValue()); } } return result; } /** * Transforms this into a range. Fails if there are no values in the list. Has no effect if this * is already a range. */ public void convertToRange() { if (!isRange) { isRange = true; range = Range.create(values); values = null; } } @Override public String toString() { if (isRange) { return range.toString(); } else { if (values.isEmpty()) { return "[]"; } String res = "["; res += PluginUtil.join(", ", values); res += "]"; return res; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy