use of org.checkerframework.checker.regex.qual.Regex in project checker-framework by typetools.
the class GroupCounts method testPatternCompileGroupCount.
void testPatternCompileGroupCount(@Regex String r, @Regex(3) String r3, @Regex(5) String r5) {
@Regex(5) Pattern p1 = Pattern.compile(r5);
@Regex Pattern p2 = Pattern.compile(r5);
@Regex Pattern p3 = Pattern.compile(r);
// :: error: (assignment.type.incompatible)
// error
@Regex(6) Pattern p4 = Pattern.compile(r5);
// :: error: (assignment.type.incompatible)
// error
@Regex(6) Pattern p5 = Pattern.compile(r3);
// Make sure Pattern.compile still works when passed an @Unqualified String
// that's actually a regex, with the warning suppressed.
@SuppressWarnings("regex:argument.type.incompatible") Pattern p6 = Pattern.compile("(" + r + ")");
}
use of org.checkerframework.checker.regex.qual.Regex in project checker-framework by typetools.
the class RegexVisitor method visitMethodInvocation.
/**
* Case 1: Don't require a Regex annotation on the String argument to Pattern.compile if the
* Pattern.LITERAL flag is passed.
*/
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
ProcessingEnvironment env = checker.getProcessingEnvironment();
if (TreeUtils.isMethodInvocation(node, patternCompile, env)) {
ExpressionTree flagParam = node.getArguments().get(1);
if (flagParam.getKind() == Kind.MEMBER_SELECT) {
MemberSelectTree memSelect = (MemberSelectTree) flagParam;
if (TreeUtils.isSpecificFieldAccess(memSelect, patternLiteral)) {
// This is a call to Pattern.compile with the Pattern.LITERAL
// flag so the first parameter doesn't need to be a
// @Regex String. Don't call the super method to skip checking
// if the first parameter is a @Regex String, but make sure to
// still recurse on all of the different parts of the method call.
Void r = scan(node.getTypeArguments(), p);
r = reduce(scan(node.getMethodSelect(), p), r);
r = reduce(scan(node.getArguments(), p), r);
return r;
}
}
} else if (TreeUtils.isMethodInvocation(node, matchResultEnd, env) || TreeUtils.isMethodInvocation(node, matchResultGroup, env) || TreeUtils.isMethodInvocation(node, matchResultStart, env)) {
/**
* Case 3: Checks calls to {@code MatchResult.start}, {@code MatchResult.end} and {@code
* MatchResult.group} to ensure that a valid group number is passed.
*/
ExpressionTree group = node.getArguments().get(0);
if (group.getKind() == Kind.INT_LITERAL) {
LiteralTree literal = (LiteralTree) group;
int paramGroups = (Integer) literal.getValue();
ExpressionTree receiver = TreeUtils.getReceiverTree(node);
if (receiver == null) {
// is out of the scope of this checker.
return super.visitMethodInvocation(node, p);
}
int annoGroups = 0;
AnnotatedTypeMirror receiverType = atypeFactory.getAnnotatedType(receiver);
if (receiverType != null && receiverType.hasAnnotation(Regex.class)) {
annoGroups = atypeFactory.getGroupCount(receiverType.getAnnotation(Regex.class));
}
if (paramGroups > annoGroups) {
checker.report(Result.failure("group.count.invalid", paramGroups, annoGroups, receiver), group);
}
} else {
checker.report(Result.warning("group.count.unknown"), group);
}
}
return super.visitMethodInvocation(node, p);
}
Aggregations