use of org.checkerframework.checker.index.qual.HasSubsequence in project checker-framework by typetools.
the class UpperBoundVisitor method visitAnnotation.
/**
* Warns about LTLengthOf annotations with arguments whose lengths do not match.
*/
@Override
public Void visitAnnotation(AnnotationTree node, Void p) {
AnnotationMirror anno = TreeUtils.annotationFromAnnotationTree(node);
if (atypeFactory.areSameByClass(anno, LTLengthOf.class)) {
List<? extends ExpressionTree> args = node.getArguments();
if (args.size() == 2) {
// If offsets are provided, there must be the same number of them as there are arrays.
List<String> sequences = AnnotationUtils.getElementValueArray(anno, atypeFactory.ltLengthOfValueElement, String.class);
List<String> offsets = AnnotationUtils.getElementValueArray(anno, atypeFactory.ltLengthOfOffsetElement, String.class, Collections.emptyList());
if (sequences.size() != offsets.size() && !offsets.isEmpty()) {
checker.reportError(node, "different.length.sequences.offsets", sequences.size(), offsets.size());
return null;
}
}
} else if (atypeFactory.areSameByClass(anno, HasSubsequence.class)) {
// Check that the arguments to a HasSubsequence annotation are valid JavaExpressions,
// and issue an error if one of them is not.
String seq = atypeFactory.hasSubsequenceSubsequenceValue(anno);
String from = atypeFactory.hasSubsequenceFromValue(anno);
String to = atypeFactory.hasSubsequenceToValue(anno);
// check that each expression is parsable at the declaration of this class
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
checkEffectivelyFinalAndParsable(seq, enclosingClass, node);
checkEffectivelyFinalAndParsable(from, enclosingClass, node);
checkEffectivelyFinalAndParsable(to, enclosingClass, node);
}
return super.visitAnnotation(node, p);
}
use of org.checkerframework.checker.index.qual.HasSubsequence in project checker-framework by typetools.
the class UpperBoundVisitor method commonAssignmentCheck.
@Override
protected void commonAssignmentCheck(Tree varTree, ExpressionTree valueTree, @CompilerMessageKey String errorKey, Object... extraArgs) {
// check that when an assignment to a variable b declared as @HasSubsequence(a, from, to)
// occurs, to <= a.length, i.e. to is @LTEqLengthOf(a).
Subsequence subSeq = Subsequence.getSubsequenceFromTree(varTree, atypeFactory);
if (subSeq != null) {
AnnotationMirror anm;
try {
anm = atypeFactory.getAnnotationMirrorFromJavaExpressionString(subSeq.to, varTree, getCurrentPath());
} catch (JavaExpressionParseException e) {
anm = null;
}
boolean ltelCheckFailed = true;
if (anm != null) {
UBQualifier qual = UBQualifier.createUBQualifier(anm, (UpperBoundChecker) checker);
ltelCheckFailed = !qual.isLessThanOrEqualTo(subSeq.array);
}
if (ltelCheckFailed) {
// issue an error
checker.reportError(valueTree, TO_NOT_LTEL, subSeq.to, subSeq.array, anm == null ? "@UpperBoundUnknown" : anm, subSeq.array, subSeq.array, subSeq.array);
} else {
checker.reportWarning(valueTree, HSS, subSeq.array, subSeq.from, subSeq.from, subSeq.to, subSeq.to, subSeq.array, subSeq.array);
}
}
super.commonAssignmentCheck(varTree, valueTree, errorKey, extraArgs);
}
use of org.checkerframework.checker.index.qual.HasSubsequence in project checker-framework by typetools.
the class Subsequence method getSubsequenceFromReceiver.
/**
* Returns a Subsequence representing the {@link HasSubsequence} annotation on the declaration of
* {@code rec} or null if there is not such annotation.
*
* @param expr some tree
* @param factory an AnnotatedTypeFactory
* @return null or a new Subsequence from the declaration of {@code varTree}
*/
public static Subsequence getSubsequenceFromReceiver(JavaExpression expr, BaseAnnotatedTypeFactoryForIndexChecker factory) {
if (!(expr instanceof FieldAccess)) {
return null;
}
FieldAccess fa = (FieldAccess) expr;
VariableElement element = fa.getField();
AnnotationMirror hasSub = factory.getDeclAnnotation(element, HasSubsequence.class);
if (hasSub == null) {
return null;
}
String array = standardizeAndViewpointAdapt(factory.hasSubsequenceSubsequenceValue(hasSub), fa, factory.getChecker());
String from = standardizeAndViewpointAdapt(factory.hasSubsequenceFromValue(hasSub), fa, factory.getChecker());
String to = standardizeAndViewpointAdapt(factory.hasSubsequenceToValue(hasSub), fa, factory.getChecker());
return new Subsequence(array, from, to);
}
Aggregations