import java.util.regex.Pattern;
import org.checkerframework.checker.regex.qual.Regex;
public class Simple {
void regString() {
String s1 = "validRegex";
String s2 = "(InvalidRegex";
}
void validRegString() {
@Regex String s1 = "validRegex";
//:: error: (assignment.type.incompatible)
@Regex String s2 = "(InvalidRegex"; // error
}
void compileCall() {
Pattern.compile("test.*[^123]$");
//:: error: (argument.type.incompatible)
Pattern.compile("$test.*[^123"); // error
}
void requireValidReg(@Regex String reg, String nonReg) {
Pattern.compile(reg);
//:: error: (argument.type.incompatible)
Pattern.compile(nonReg); // error
}
void testAddition(@Regex String reg, String nonReg) {
@Regex String s1 = reg;
@Regex String s2 = reg + "d.*sf";
@Regex String s3 = reg + reg;
//:: error: (assignment.type.incompatible)
@Regex String n1 = nonReg; // error
//:: error: (assignment.type.incompatible)
@Regex String n2 = reg + "(df"; // error
//:: error: (assignment.type.incompatible)
@Regex String n3 = reg + nonReg; // error
//:: error: (assignment.type.incompatible)
@Regex String o1 = nonReg; // error
//:: error: (assignment.type.incompatible)
@Regex String o2 = nonReg + "sdf"; // error
//:: error: (assignment.type.incompatible)
@Regex String o3 = nonReg + reg; // error
}
@Regex String regex = "()";
String nonRegex = "()";
void testCompoundConcatenation() {
takesRegex(regex);
//:: error: (compound.assignment.type.incompatible)
regex += ")"; // error
takesRegex(regex);
nonRegex = "()";
// nonRegex is refined by flow to be a regular expression
takesRegex(nonRegex);
nonRegex += ")";
//:: error: (argument.type.incompatible)
takesRegex(nonRegex); // error
}
void takesRegex(@Regex String s) {}
void testChar() {
@Regex char c1 = 'c';
@Regex Character c2 = 'c';
//:: error: (assignment.type.incompatible)
@Regex char c3 = '('; // error
//:: error: (assignment.type.incompatible)
@Regex Character c4 = '('; // error
}
void testCharConcatenation() {
@Regex String s1 = "rege" + 'x';
@Regex String s2 = 'r' + "egex";
//:: error: (assignment.type.incompatible)
@Regex String s4 = "rege" + '('; // error
//:: error: (assignment.type.incompatible)
@Regex String s5 = "reg(" + 'x'; // error
//:: error: (assignment.type.incompatible)
@Regex String s6 = '(' + "egex"; // error
//:: error: (assignment.type.incompatible)
@Regex String s7 = 'r' + "ege("; // error
}
// TODO: Uncomment this once isValidUse works better. See RegexChecker.isValidUse for details.
// class TestAllowedTypes {
// @Regex CharSequence cs;
// @Regex String s11;
// @Regex StringBuilder sb;
// @Regex Segment s21;
// @Regex char c;
// @Regex Pattern p;
// @Regex Matcher m;
//
// //:: error: (type.invalid)
// @Regex Object o; // error
// //:: error: (type.invalid)
// @Regex List<String> l; // error
// //:: error: (type.invalid)
// ArrayList<@Regex Double> al; // error
// //:: error: (type.invalid)
// @Regex int i; // error
// //:: error: (type.invalid)
// @Regex boolean b; // error
// }
// TODO: This is not supported until the checker supports getting explicit
// annotations from local variables (instead of just fields.)
// void testAllowedTypes() {
// @Regex CharSequence cs;
// @Regex String s11;
// @Regex StringBuilder sb;
// @Regex Segment s21;
// @Regex char c;
//
// //:: error: (type.invalid)
// @Regex Object o; // error
// //:: error: (type.invalid)
// @Regex List<String> l; // error
// //:: error: (type.invalid)
// ArrayList<@Regex Double> al; // error
// //:: error: (type.invalid)
// @Regex int i; // error
// //:: error: (type.invalid)
// @Regex boolean b; // error
//
// @Regex String regex = "a";
// //:: error: (argument.type.incompatible)
// regex += "(";
//
// String nonRegex = "a";
// nonRegex += "(";
// }
void testPatternLiteral() {
Pattern.compile("non(", Pattern.LITERAL);
Pattern.compile(foo("regex"), Pattern.LITERAL);
//:: error: (argument.type.incompatible)
Pattern.compile(foo("regex("), Pattern.LITERAL); // error
//:: error: (argument.type.incompatible)
Pattern.compile("non("); // error
//:: error: (argument.type.incompatible)
Pattern.compile(foo("regex")); // error
//:: error: (argument.type.incompatible)
Pattern.compile("non(", Pattern.CASE_INSENSITIVE); // error
}
public static String foo(@Regex String s) {
return "non((";
}
// TODO: This is not supported until the framework can read explicit
// annotations from arrays.
// void testArrayAllowedTypes() {
// @Regex char[] ca1;
// char @Regex [] ca2;
// @Regex char @Regex [] ca3;
// @Regex String[] s1;
//
// //:: error: (type.invalid)
// @Regex double[] da1; // error
// //:: error: (type.invalid)
// double @Regex [] da2; // error
// //:: error: (type.invalid)
// @Regex double @Regex [] da3; // error
// //:: error: (type.invalid)
// String @Regex [] s2; // error
// }
// TODO: This is not supported until the Regex Checker supports flow
// sensitivity. See the associated comment at
// org.checkerframework.checker/regex/RegexAnnotatedTypeFactory.java:visitNewArray
// void testCharArrays(char c, @Regex char r) {
// char @Regex [] c1 = {'r', 'e', 'g', 'e', 'x'};
// char @Regex [] c2 = {'(', 'r', 'e', 'g', 'e', 'x', ')', '.', '*'};
// char @Regex [] c3 = {r, 'e', 'g', 'e', 'x'};
//
// //:: error: (assignment.type.incompatible)
// char @Regex [] c4 = {'(', 'r', 'e', 'g', 'e', 'x'}; // error
// //:: error: (assignment.type.incompatible)
// char @Regex [] c5 = {c, '.', '*'}; // error
// }
}