AbstractRegexCheck extends AbstractMethodDetection implements RegexCheck { @VisibleForTesting protected static Optional<LiteralTree[]> getLiterals(ExpressionTree expr) { switch (expr.kind()) { case PLUS: return getLiteralsFromStringConcatenation((BinaryExpressionTree) expr); case IDENTIFIER: return getLiteralsFromFinalVariables((IdentifierTree) expr); case PARENTHESIZED_EXPRESSION: return getLiterals(ExpressionUtils.skipParentheses(expr)); case STRING_LITERAL: return Optional.of(new LiteralTree[] {(LiteralTree) expr}); default: return Optional.empty(); } }  @Override final void setContext(JavaFileScannerContext context); @Override List<Tree.Kind> nodesToVisit(); abstract void checkRegex(RegexParseResult regexForLiterals, MethodInvocationTree mit); final void reportIssue(RegexSyntaxElement regexTree, String message, @Nullable Integer cost, List<RegexCheck.RegexIssueLocation> secondaries); final void reportIssue(Tree javaTree, String message, @Nullable Integer cost, List<RegexCheck.RegexIssueLocation> secondaries);  }
@Test void test_GetLiterals_string_literals() { ExpressionTree expr = getArg("\"hello\"").expr; Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isPresent(); assertThat(result.get()) .hasSize(1) .allMatch(t -> t.is(Tree.Kind.STRING_LITERAL)) .containsExactly((LiteralTree) expr); }
@Test void test_GetLiterals_effectively_final_variable() { TestCase testcase = getArg("a", "String a = \"abc\";"); ExpressionTree expr = testcase.expr; ExpressionTree initializer = ((VariableTree) testcase.preStatements.get(0)).initializer(); Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isPresent(); assertThat(result.get()) .hasSize(1) .allMatch(t -> t.is(Tree.Kind.STRING_LITERAL)) .containsExactly((LiteralTree) initializer); }
@Test void test_GetLiterals_effectively_non_final_variable() { TestCase testcase = getArg("a", "String a = \"abc\";", "a = \"bcd\";"); ExpressionTree expr = testcase.expr; Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isEmpty(); }
@Test void test_GetLiterals_final_variable() { TestCase testcase = getArg("a", "final String a = \"abc\";"); ExpressionTree expr = testcase.expr; ExpressionTree initializer = ((VariableTree) testcase.preStatements.get(0)).initializer(); Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isPresent(); assertThat(result.get()) .hasSize(1) .allMatch(t -> t.is(Tree.Kind.STRING_LITERAL)) .containsExactly((LiteralTree) initializer); }
@Test void test_GetLiterals_constant_outside_file() { TestCase testcase = getArg("MULTILINE"); ExpressionTree expr = testcase.expr; Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isEmpty(); }
@Test void test_GetLiterals_constant_within_file() { TestCase testcase = getArg("A_CONST"); ExpressionTree expr = testcase.expr; ExpressionTree initializer = ((VariableTree) (((IdentifierTree) expr).symbol().declaration())).initializer(); Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isPresent(); assertThat(result.get()) .hasSize(1) .allMatch(t -> t.is(Tree.Kind.STRING_LITERAL)) .containsExactly((LiteralTree) initializer); }
@Test void test_GetLiterals_final_variable_not_directly_initialized() { TestCase testcase = getArg("a", "final String a;", "a = \"abc\";"); ExpressionTree expr = testcase.expr; Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isEmpty(); }
@Test void test_GetLiterals_string_concatenation() { TestCase testcase = getArg("\"a\" + \"b\" + \"c\""); ExpressionTree expr = testcase.expr; BinaryExpressionTree ab = (BinaryExpressionTree) ((BinaryExpressionTree) expr).leftOperand(); ExpressionTree a = ab.leftOperand(); ExpressionTree b = ab.rightOperand(); ExpressionTree c = ((BinaryExpressionTree) expr).rightOperand(); Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isPresent(); assertThat(result.get()) .hasSize(3) .allMatch(t -> t.is(Tree.Kind.STRING_LITERAL)) .containsExactly((LiteralTree) a, (LiteralTree) b, (LiteralTree) c); }
@Test void test_GetLiterals_string_concatenation_with_constant() { TestCase testcase = getArg("\"a\" + b + \"c\"", "final String b = \"q\";"); ExpressionTree expr = testcase.expr; BinaryExpressionTree ab = (BinaryExpressionTree) ((BinaryExpressionTree) expr).leftOperand(); ExpressionTree a = ab.leftOperand(); ExpressionTree b = ((VariableTree) (testcase.preStatements.get(0))).initializer(); ExpressionTree c = ((BinaryExpressionTree) expr).rightOperand(); Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isPresent(); assertThat(result.get()) .hasSize(3) .allMatch(t -> t.is(Tree.Kind.STRING_LITERAL)) .containsExactly((LiteralTree) a, (LiteralTree) b, (LiteralTree) c); }
@Test void test_GetLiterals_string_concatenation_with_constant_and_parenthesis() { TestCase testcase = getArg("\"a\" + (b + \"c\")", "final String b = \"q\";"); ExpressionTree expr = testcase.expr; ExpressionTree a = ((BinaryExpressionTree) expr).leftOperand(); BinaryExpressionTree bc = (BinaryExpressionTree) ((ParenthesizedTree) ((BinaryExpressionTree) expr).rightOperand()).expression(); ExpressionTree b = ((VariableTree) (testcase.preStatements.get(0))).initializer(); ExpressionTree c = bc.rightOperand(); Optional<LiteralTree[]> result = getLiterals(expr); assertThat(result).isPresent(); assertThat(result.get()) .hasSize(3) .allMatch(t -> t.is(Tree.Kind.STRING_LITERAL)) .containsExactly((LiteralTree) a, (LiteralTree) b, (LiteralTree) c); }