diff --git a/ql/src/codeql_ruby/ast/Expr.qll b/ql/src/codeql_ruby/ast/Expr.qll index 7b6537e8166..dedcf04de4e 100644 --- a/ql/src/codeql_ruby/ast/Expr.qll +++ b/ql/src/codeql_ruby/ast/Expr.qll @@ -24,6 +24,23 @@ class Self extends Expr, @token_self { final override string getAPrimaryQlClass() { result = "Self" } } +/** + * A sequence of expressions in the right-hand side of an assignment or + * a `return`, `break` or `next` statement. + * ```rb + * x = 1, *items, 3, *more + * return 1, 2 + * next *list + * break **map + * return 1, 2, *items, k: 5, **map + * ``` + */ +class ArgumentList extends Expr { + override ArgumentList::Range range; + + override string getAPrimaryQlClass() { result = "ArgumentList" } +} + /** A sequence of expressions. */ class StmtSequence extends Expr { override StmtSequence::Range range; diff --git a/ql/src/codeql_ruby/ast/internal/Expr.qll b/ql/src/codeql_ruby/ast/internal/Expr.qll index 337589a5653..194ba71971b 100644 --- a/ql/src/codeql_ruby/ast/internal/Expr.qll +++ b/ql/src/codeql_ruby/ast/internal/Expr.qll @@ -16,6 +16,36 @@ module Self { } } +module ArgumentList { + private class ValidParent = @break or @return or @next or @assignment or @operator_assignment; + + abstract class Range extends Expr::Range { + Range() { generated.getParent() instanceof ValidParent } + + abstract Expr getElement(int i); + + final override string toString() { result = "..., ..." } + + override predicate child(string label, AstNode::Range child) { + label = "getElement" and child = getElement(_) + } + } + + private class ArgArgumentList extends ArgumentList::Range, @argument_list { + final override Generated::ArgumentList generated; + + ArgArgumentList() { count(generated.getChild(_)) != 1 } + + final override Expr getElement(int i) { result = generated.getChild(i) } + } + + private class AssignmentList extends ArgumentList::Range, @right_assignment_list { + final override Generated::RightAssignmentList generated; + + final override Expr getElement(int i) { result = generated.getChild(i) } + } +} + module StmtSequence { abstract class Range extends Expr::Range { abstract Stmt getStmt(int n);