|
76 | 76 | #' @seealso [linters] for a complete list of linters available in lintr. |
77 | 77 | #' @export |
78 | 78 | unreachable_code_linter <- function(allow_comment_regex = getOption("covr.exclude_end", "# nocov end")) { |
79 | | - # nolint next: object_usage_linter. Used in glue() in statically-difficult fashion to detect. |
80 | 79 | expr_after_control <- " |
81 | 80 | (//REPEAT | //ELSE | //FOR)/following-sibling::expr[1] |
82 | 81 | | (//IF | //WHILE)/following-sibling::expr[2] |
83 | 82 | " |
84 | | - |
85 | | - unreachable_expr_cond_ws <- " |
86 | | - following-sibling::*[ |
87 | | - not(self::OP-RIGHT-BRACE or self::OP-SEMICOLON or self::ELSE or preceding-sibling::ELSE) |
88 | | - and (not(self::COMMENT) or @line2 > preceding-sibling::*[not(self::COMMENT)][1]/@line2) |
89 | | - ][1]" |
90 | | - # when a semicolon is present, the condition is a bit different due to <exprlist> nodes |
91 | | - unreachable_expr_cond_sc <- " |
92 | | - parent::exprlist[OP-SEMICOLON] |
93 | | - /following-sibling::*[ |
94 | | - not(self::OP-RIGHT-BRACE) |
95 | | - and (not(self::COMMENT) or @line1 > preceding-sibling::exprlist/expr/@line2) |
96 | | - ][1] |
97 | | - " |
98 | | - |
99 | 83 | # NB: use not(OP-DOLLAR) to prevent matching process$stop(), #1051 |
100 | | - xpath_return_stop_fmt <- " |
| 84 | + xpath_return_stop <- glue(" |
101 | 85 | ( |
102 | 86 | {expr_after_control} |
103 | | - | |
104 | | - (//FUNCTION | //OP-LAMBDA) |
105 | | - /following-sibling::expr[OP-LEFT-BRACE][last()] |
| 87 | + | (//FUNCTION | //OP-LAMBDA)[following-sibling::expr[1]/*[1][self::OP-LEFT-BRACE]]/following-sibling::expr[1] |
106 | 88 | ) |
107 | | - //expr[expr[1][ |
| 89 | + /expr[expr[1][ |
108 | 90 | not(OP-DOLLAR or OP-AT) |
109 | 91 | and SYMBOL_FUNCTION_CALL[text() = 'return' or text() = 'stop'] |
110 | 92 | ]] |
111 | | - /{unreachable_expr_cond} |
112 | | - " |
113 | | - xpath_return_stop <- paste( |
114 | | - glue(xpath_return_stop_fmt, unreachable_expr_cond = unreachable_expr_cond_ws), |
115 | | - glue(xpath_return_stop_fmt, unreachable_expr_cond = unreachable_expr_cond_sc), |
116 | | - sep = " | " |
117 | | - ) |
118 | | - xpath_next_break_fmt <- " |
| 93 | + /following-sibling::*[ |
| 94 | + not(self::OP-RIGHT-BRACE or self::OP-SEMICOLON) |
| 95 | + and (not(self::COMMENT) or @line2 > preceding-sibling::*[1]/@line2) |
| 96 | + ][1] |
| 97 | + ") |
| 98 | + xpath_next_break <- glue(" |
119 | 99 | ({expr_after_control}) |
120 | | - //expr[NEXT or BREAK] |
121 | | - /{unreachable_expr_cond} |
122 | | - " |
123 | | - xpath_next_break <- paste( |
124 | | - glue(xpath_next_break_fmt, unreachable_expr_cond = unreachable_expr_cond_ws), |
125 | | - glue(xpath_next_break_fmt, unreachable_expr_cond = unreachable_expr_cond_sc), |
126 | | - sep = " | " |
127 | | - ) |
| 100 | + /expr[NEXT or BREAK] |
| 101 | + /following-sibling::*[ |
| 102 | + not(self::OP-RIGHT-BRACE or self::OP-SEMICOLON) |
| 103 | + and (not(self::COMMENT) or @line2 > preceding-sibling::*[1]/@line2) |
| 104 | + ][1] |
| 105 | + ") |
128 | 106 |
|
129 | 107 | xpath_if_while <- " |
130 | 108 | (//WHILE | //IF)[following-sibling::expr[1]/NUM_CONST[text() = 'FALSE']] |
|
0 commit comments