(
context: &mut ParserContext,
env: &mut Environment,
tokens: &[Token],
position: &mut usize,
)
| 149 | } |
| 150 | |
| 151 | pub(crate) fn parse_regex_expression( |
| 152 | context: &mut ParserContext, |
| 153 | env: &mut Environment, |
| 154 | tokens: &[Token], |
| 155 | position: &mut usize, |
| 156 | ) -> Result<Box<dyn Expr>, Box<Diagnostic>> { |
| 157 | let lhs = parse_is_null_expression(context, env, tokens, position)?; |
| 158 | |
| 159 | // Check for `REGEXP` or `NOT REGEXP` |
| 160 | // <expr> REGEXP <expr> AND <expr> |
| 161 | // <expr> NOT REGEXP <expr> AND <expr> |
| 162 | if is_current_token(tokens, position, TokenKind::RegExp) |
| 163 | || (is_current_token(tokens, position, TokenKind::Not) |
| 164 | && is_next_token(tokens, position, TokenKind::RegExp)) |
| 165 | { |
| 166 | let has_not_keyword = is_current_token(tokens, position, TokenKind::Not); |
| 167 | let operator_location = if has_not_keyword { |
| 168 | // Consume `NOT` and `REGEXP` keyword |
| 169 | *position += 2; |
| 170 | let mut not_location = tokens[*position - 2].location; |
| 171 | let between_location = tokens[*position - 1].location; |
| 172 | not_location.expand_until(between_location); |
| 173 | not_location |
| 174 | } else { |
| 175 | // Consume `REGEXP` keyword |
| 176 | *position += 1; |
| 177 | tokens[*position - 1].location |
| 178 | }; |
| 179 | |
| 180 | let pattern = parse_is_null_expression(context, env, tokens, position)?; |
| 181 | |
| 182 | let lhs_type = lhs.expr_type(); |
| 183 | let rhs_type = pattern.expr_type(); |
| 184 | |
| 185 | // Can perform this operator between LHS and RHS |
| 186 | let expected_rhs_types = lhs_type.can_perform_regexp_op_with(); |
| 187 | if expected_rhs_types.contains(&rhs_type) { |
| 188 | let regex_expr = Box::new(RegexExpr { |
| 189 | input: lhs, |
| 190 | pattern, |
| 191 | }); |
| 192 | |
| 193 | return Ok(apply_not_keyword_if_exists(regex_expr, has_not_keyword)); |
| 194 | } |
| 195 | |
| 196 | // Check if RHS expr can be implicit casted to Expected LHS type to make this |
| 197 | // Expression valid |
| 198 | for expected_type in expected_rhs_types.iter() { |
| 199 | if !expected_type.has_implicit_cast_from(&pattern) { |
| 200 | continue; |
| 201 | } |
| 202 | |
| 203 | let casting = Box::new(CastExpr { |
| 204 | value: pattern, |
| 205 | result_type: expected_type.clone(), |
| 206 | }); |
| 207 | |
| 208 | let expr = Box::new(RegexExpr { |
no test coverage detected
searching dependent graphs…