(
context: &mut ParserContext,
env: &mut Environment,
tokens: &[Token],
position: &mut usize,
)
| 3211 | } |
| 3212 | |
| 3213 | pub(crate) fn parse_member_access_expression( |
| 3214 | context: &mut ParserContext, |
| 3215 | env: &mut Environment, |
| 3216 | tokens: &[Token], |
| 3217 | position: &mut usize, |
| 3218 | ) -> Result<Box<dyn Expr>, Box<Diagnostic>> { |
| 3219 | let expr = parse_primary_expression(context, env, tokens, position)?; |
| 3220 | |
| 3221 | if is_current_token(tokens, position, TokenKind::Dot) { |
| 3222 | let dot_token = &tokens[*position]; |
| 3223 | |
| 3224 | // The syntax for member access is (composite).member |
| 3225 | // The composite expr must be in group, that make it different from table access table.name |
| 3226 | if expr.kind() != ExprKind::Column { |
| 3227 | return Err( |
| 3228 | Diagnostic::error("Dot token expect composite value between `(` and `)`") |
| 3229 | .add_note("The syntax for accessing composite element is (composite).member") |
| 3230 | .with_location(dot_token.location) |
| 3231 | .as_boxed(), |
| 3232 | ); |
| 3233 | } |
| 3234 | |
| 3235 | // Consume `.` token |
| 3236 | *position += 1; |
| 3237 | |
| 3238 | // select (user).name from users |
| 3239 | if let Some(composite_type) = expr.expr_type().as_any().downcast_ref::<CompositeType>() { |
| 3240 | if *position < tokens.len() && matches!(tokens[*position].kind, TokenKind::Symbol(_)) { |
| 3241 | let member_token = &tokens[*position]; |
| 3242 | |
| 3243 | // Consume `Symbol` token |
| 3244 | *position += 1; |
| 3245 | |
| 3246 | let member_name = member_token.to_string(); |
| 3247 | |
| 3248 | // Make sure the member name is valid for this composite type |
| 3249 | if !composite_type.members.contains_key(&member_name) { |
| 3250 | return Err(Diagnostic::error(&format!( |
| 3251 | "Compose type {} has no member with name {}", |
| 3252 | composite_type.name, member_name |
| 3253 | )) |
| 3254 | .add_help("Check the Composite type to see what are his members") |
| 3255 | .with_location(member_token.location) |
| 3256 | .as_boxed()); |
| 3257 | } |
| 3258 | |
| 3259 | let member_type = composite_type.members.get(&member_name).unwrap().clone(); |
| 3260 | return Ok(Box::new(MemberAccessExpr { |
| 3261 | composite: expr, |
| 3262 | member_name, |
| 3263 | member_type, |
| 3264 | })); |
| 3265 | } |
| 3266 | |
| 3267 | // Member Access expect symbol as member name |
| 3268 | return Err(Diagnostic::error("Member access expect symbol after `.`") |
| 3269 | .add_note("The syntax for accessing composite element is (composite).member") |
| 3270 | .with_location(dot_token.location) |
no test coverage detected
searching dependent graphs…