Skip to content

Commit 9f48ae6

Browse files
authored
Merge pull request #7306 from aibaars/ruby-parenthesized-pattern
Ruby: parenthesized patterns
2 parents 4ae9959 + 0805daa commit 9f48ae6

File tree

16 files changed

+3143
-129
lines changed

16 files changed

+3143
-129
lines changed

ruby/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ruby/extractor/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ flate2 = "1.0"
1111
node-types = { path = "../node-types" }
1212
tree-sitter = "0.19"
1313
tree-sitter-embedded-template = "0.19"
14-
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "951799c6780deaabb0666b846cb7ad4eab627bbb" }
14+
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "888e2e563ed3b43c417f17e57f7e29c39ce9aeea" }
1515
clap = "2.33"
1616
tracing = "0.1"
1717
tracing-subscriber = { version = "0.2", features = ["env-filter"] }

ruby/generator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ node-types = { path = "../node-types" }
1212
tracing = "0.1"
1313
tracing-subscriber = { version = "0.2", features = ["env-filter"] }
1414
tree-sitter-embedded-template = "0.19"
15-
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "951799c6780deaabb0666b846cb7ad4eab627bbb" }
15+
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "888e2e563ed3b43c417f17e57f7e29c39ce9aeea" }

ruby/ql/lib/codeql/ruby/ast/Pattern.qll

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class TuplePattern extends Pattern, TTuplePattern {
100100

101101
private class TPatternNode =
102102
TArrayPattern or TFindPattern or THashPattern or TAlternativePattern or TAsPattern or
103-
TVariableReferencePattern;
103+
TParenthesizedPattern or TVariableReferencePattern;
104104

105105
private class TPattern =
106106
TPatternNode or TLiteral or TLambda or TConstantAccess or TLocalVariableAccess or
@@ -389,6 +389,31 @@ class AsPattern extends CasePattern, TAsPattern {
389389
}
390390
}
391391

392+
/**
393+
* A parenthesized pattern:
394+
* ```rb
395+
* in (1 ..)
396+
* in (0 | "" | [] | {})
397+
* ```
398+
*/
399+
class ParenthesizedPattern extends CasePattern, TParenthesizedPattern {
400+
private Ruby::ParenthesizedPattern g;
401+
402+
ParenthesizedPattern() { this = TParenthesizedPattern(g) }
403+
404+
final CasePattern getPattern() { toGenerated(result) = g.getChild() }
405+
406+
final override string getAPrimaryQlClass() { result = "ParenthesizedPattern" }
407+
408+
final override string toString() { result = "( ... )" }
409+
410+
final override AstNode getAChild(string pred) {
411+
result = super.getAChild(pred)
412+
or
413+
pred = "getPattern" and result = this.getPattern()
414+
}
415+
}
416+
392417
/**
393418
* A variable reference in a pattern, i.e. `^x` in the following example:
394419
* ```rb

ruby/ql/lib/codeql/ruby/ast/internal/AST.qll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ private module Cached {
216216
TOptionalParameter(Ruby::OptionalParameter g) or
217217
TPair(Ruby::Pair g) or
218218
TParenthesizedExpr(Ruby::ParenthesizedStatements g) or
219+
TParenthesizedPattern(Ruby::ParenthesizedPattern g) or
219220
TRShiftExprReal(Ruby::Binary g) { g instanceof @ruby_binary_ranglerangle } or
220221
TRShiftExprSynth(AST::AstNode parent, int i) { mkSynthChild(RShiftExprKind(), parent, i) } or
221222
TRangeLiteralReal(Ruby::Range g) or
@@ -335,10 +336,10 @@ private module Cached {
335336
TLeftAssignmentList or TLine or TLocalVariableAccessReal or TLogicalAndExprReal or
336337
TLogicalOrExprReal or TMethod or TModuleDeclaration or TModuloExprReal or TMulExprReal or
337338
TNEExpr or TNextStmt or TNilLiteral or TNoRegExpMatchExpr or TNotExpr or
338-
TOptionalParameter or TPair or TParenthesizedExpr or TRShiftExprReal or TRangeLiteralReal or
339-
TRationalLiteral or TRedoStmt or TRegExpLiteral or TRegExpMatchExpr or
340-
TRegularArrayLiteral or TRegularMethodCall or TRegularStringLiteral or TRegularSuperCall or
341-
TRescueClause or TRescueModifierExpr or TRetryStmt or TReturnStmt or
339+
TOptionalParameter or TPair or TParenthesizedExpr or TParenthesizedPattern or
340+
TRShiftExprReal or TRangeLiteralReal or TRationalLiteral or TRedoStmt or TRegExpLiteral or
341+
TRegExpMatchExpr or TRegularArrayLiteral or TRegularMethodCall or TRegularStringLiteral or
342+
TRegularSuperCall or TRescueClause or TRescueModifierExpr or TRetryStmt or TReturnStmt or
342343
TScopeResolutionConstantAccess or TScopeResolutionMethodCall or TSelfReal or
343344
TSimpleParameterReal or TSimpleSymbolLiteral or TSingletonClass or TSingletonMethod or
344345
TSpaceshipExpr or TSplatExprReal or TSplatParameter or TStringArrayLiteral or
@@ -465,6 +466,7 @@ private module Cached {
465466
n = TOptionalParameter(result) or
466467
n = TPair(result) or
467468
n = TParenthesizedExpr(result) or
469+
n = TParenthesizedPattern(result) or
468470
n = TRangeLiteralReal(result) or
469471
n = TRationalLiteral(result) or
470472
n = TRedoStmt(result) or

ruby/ql/lib/codeql/ruby/ast/internal/Pattern.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ predicate casePattern(Ruby::AstNode node) {
4646
node = any(Ruby::AsPattern parent).getValue()
4747
or
4848
node = any(Ruby::KeywordPattern parent).getValue()
49+
or
50+
node = any(Ruby::ParenthesizedPattern parent).getChild()
4951
}
5052

5153
/**

ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,21 @@ module Ruby {
14061406
}
14071407
}
14081408

1409+
/** A class representing `parenthesized_pattern` nodes. */
1410+
class ParenthesizedPattern extends @ruby_parenthesized_pattern, AstNode {
1411+
/** Gets the name of the primary QL class for this element. */
1412+
override string getAPrimaryQlClass() { result = "ParenthesizedPattern" }
1413+
1414+
/** Gets the location of this element. */
1415+
override L::Location getLocation() { ruby_parenthesized_pattern_def(this, _, result) }
1416+
1417+
/** Gets the child of this node. */
1418+
UnderscorePatternExpr getChild() { ruby_parenthesized_pattern_def(this, result, _) }
1419+
1420+
/** Gets a field or child node of this node. */
1421+
override AstNode getAFieldOrChild() { ruby_parenthesized_pattern_def(this, result, _) }
1422+
}
1423+
14091424
/** A class representing `parenthesized_statements` nodes. */
14101425
class ParenthesizedStatements extends @ruby_parenthesized_statements, AstNode {
14111426
/** Gets the name of the primary QL class for this element. */

ruby/ql/lib/ruby.dbscheme

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ case @diagnostic.severity of
6262

6363
@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic
6464

65-
@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern
65+
@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern
6666

6767
@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric
6868

@@ -912,6 +912,12 @@ ruby_pair_def(
912912
int loc: @location ref
913913
);
914914

915+
ruby_parenthesized_pattern_def(
916+
unique int id: @ruby_parenthesized_pattern,
917+
int child: @ruby_underscore_pattern_expr ref,
918+
int loc: @location ref
919+
);
920+
915921
@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement
916922

917923
#keyset[ruby_parenthesized_statements, index]
@@ -1392,7 +1398,7 @@ case @ruby_token.kind of
13921398
;
13931399

13941400

1395-
@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_parameter | @ruby_block_parameters | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield
1401+
@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_parameter | @ruby_block_parameters | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield
13961402

13971403
@ruby_ast_node_parent = @file | @ruby_ast_node
13981404

0 commit comments

Comments
 (0)