package org.checkerframework.checker.index.samelen; /*>>> import org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey; */ import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.Tree; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.type.TypeKind; import org.checkerframework.checker.index.IndexUtil; import org.checkerframework.checker.index.qual.PolySameLen; import org.checkerframework.checker.index.qual.SameLen; import org.checkerframework.common.basetype.BaseTypeChecker; import org.checkerframework.common.basetype.BaseTypeVisitor; import org.checkerframework.dataflow.analysis.FlowExpressions; import org.checkerframework.dataflow.analysis.FlowExpressions.Receiver; import org.checkerframework.framework.type.AnnotatedTypeMirror; import org.checkerframework.javacutil.TreeUtils; public class SameLenVisitor extends BaseTypeVisitor<SameLenAnnotatedTypeFactory> { public SameLenVisitor(BaseTypeChecker checker) { super(checker); } /** * Modifies the common assignment checks to ensure that SameLen annotations are always merged. * The check is not relaxed in any way. */ @Override protected void commonAssignmentCheck( AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, Tree valueTree, /*@CompilerMessageKey*/ String errorKey) { if (valueType.getKind() == TypeKind.ARRAY && TreeUtils.isExpressionTree(valueTree) && !(valueType.hasAnnotation(PolySameLen.class) && varType.hasAnnotation(PolySameLen.class))) { AnnotationMirror am = valueType.getAnnotation(SameLen.class); List<String> arraysInAnno = am == null ? new ArrayList<String>() : IndexUtil.getValueOfAnnotationWithStringArgument(am); Receiver rec = FlowExpressions.internalReprOf(atypeFactory, (ExpressionTree) valueTree); if (rec != null && SameLenAnnotatedTypeFactory.isReceiverToStringParsable(rec)) { List<String> itself = Collections.singletonList(rec.toString()); AnnotationMirror newSameLen = atypeFactory.getCombinedSameLen(arraysInAnno, itself); valueType.replaceAnnotation(newSameLen); } } super.commonAssignmentCheck(varType, valueType, valueTree, errorKey); } }