blob: eae5199c96c7fcb7de57c77ddad5e117a6372215 [file] [log] [blame]
package org.checkerframework.checker.units;
import com.sun.source.tree.CompoundAssignmentTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.Tree.Kind;
import org.checkerframework.checker.units.qual.UnknownUnits;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.basetype.BaseTypeVisitor;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
/**
* Units visitor.
*
* <p>Ensure consistent use of compound assignments.
*/
public class UnitsVisitor extends BaseTypeVisitor<UnitsAnnotatedTypeFactory> {
public UnitsVisitor(BaseTypeChecker checker) {
super(checker);
}
@Override
public Void visitCompoundAssignment(CompoundAssignmentTree node, Void p) {
ExpressionTree var = node.getVariable();
ExpressionTree expr = node.getExpression();
AnnotatedTypeMirror varType = atypeFactory.getAnnotatedType(var);
AnnotatedTypeMirror exprType = atypeFactory.getAnnotatedType(expr);
Kind kind = node.getKind();
if ((kind == Kind.PLUS_ASSIGNMENT || kind == Kind.MINUS_ASSIGNMENT)) {
if (!atypeFactory.getTypeHierarchy().isSubtype(exprType, varType)) {
checker.reportError(node, "compound.assignment", varType, exprType);
}
} else if (exprType.getAnnotation(UnknownUnits.class) == null) {
// Only allow mul/div with unqualified units
checker.reportError(node, "compound.assignment", varType, exprType);
}
return null; // super.visitCompoundAssignment(node, p);
}
}