Skip to content

Commit 5199829

Browse files
committed
Ruby: add AST classes for parenthesized patterns
1 parent 205233b commit 5199829

File tree

8 files changed

+170
-124
lines changed

8 files changed

+170
-124
lines changed

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

Lines changed: 25 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,30 @@ class AsPattern extends CasePattern, TAsPattern {
389389
}
390390
}
391391

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

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,90 +1005,101 @@ control/cases.rb:
10051005
# 106| getAnOperand/getOperand/getReceiver: [IntegerLiteral] 5
10061006
# 106| getAlternative: [UnaryPlusExpr] + ...
10071007
# 106| getAnOperand/getOperand/getReceiver: [IntegerLiteral] 10
1008-
# 111| getStmt: [CaseExpr] case ...
1009-
# 111| getValue: [MethodCall] call to expr
1010-
# 111| getReceiver: [Self, SelfVariableAccess] self
1011-
# 112| getBranch: [InClause] in ... then ...
1012-
# 112| getPattern: [ArrayPattern] [ ..., * ]
1013-
# 113| getBranch: [InClause] in ... then ...
1014-
# 113| getPattern: [ArrayPattern] [ ..., * ]
1015-
# 113| getPrefixElement: [LocalVariableAccess] x
1008+
# 107| getBranch: [InClause] in ... then ...
1009+
# 107| getPattern: [ParenthesizedPattern] ( ... )
1010+
# 107| getPattern: [RangeLiteral] _ .. _
1011+
# 107| getBegin: [IntegerLiteral] 1
1012+
# 108| getBranch: [InClause] in ... then ...
1013+
# 108| getPattern: [ParenthesizedPattern] ( ... )
1014+
# 108| getPattern: [AlternativePattern] ... | ...
1015+
# 108| getAlternative: [IntegerLiteral] 0
1016+
# 108| getAlternative: [StringLiteral] ""
1017+
# 108| getAlternative: [ArrayPattern] [ ..., * ]
1018+
# 108| getAlternative: [HashPattern] { ..., ** }
1019+
# 113| getStmt: [CaseExpr] case ...
1020+
# 113| getValue: [MethodCall] call to expr
1021+
# 113| getReceiver: [Self, SelfVariableAccess] self
10161022
# 114| getBranch: [InClause] in ... then ...
10171023
# 114| getPattern: [ArrayPattern] [ ..., * ]
1018-
# 114| getPrefixElement/getSuffixElement: [LocalVariableAccess] x
10191024
# 115| getBranch: [InClause] in ... then ...
10201025
# 115| getPattern: [ArrayPattern] [ ..., * ]
1021-
# 115| getClass: [ConstantReadAccess] Bar
1022-
# 115| getScopeExpr: [ConstantReadAccess] Foo
1026+
# 115| getPrefixElement: [LocalVariableAccess] x
10231027
# 116| getBranch: [InClause] in ... then ...
10241028
# 116| getPattern: [ArrayPattern] [ ..., * ]
1025-
# 116| getClass: [ConstantReadAccess] Foo
1029+
# 116| getPrefixElement/getSuffixElement: [LocalVariableAccess] x
10261030
# 117| getBranch: [InClause] in ... then ...
10271031
# 117| getPattern: [ArrayPattern] [ ..., * ]
10281032
# 117| getClass: [ConstantReadAccess] Bar
1033+
# 117| getScopeExpr: [ConstantReadAccess] Foo
10291034
# 118| getBranch: [InClause] in ... then ...
10301035
# 118| getPattern: [ArrayPattern] [ ..., * ]
1031-
# 118| getClass: [ConstantReadAccess] Bar
1032-
# 118| getPrefixElement/getSuffixElement: [LocalVariableAccess] a
1033-
# 118| getPrefixElement/getSuffixElement: [LocalVariableAccess] b
1034-
# 118| getRestVariableAccess: [LocalVariableAccess] c
1035-
# 118| getSuffixElement: [LocalVariableAccess] d
1036-
# 118| getSuffixElement: [LocalVariableAccess] e
1037-
# 123| getStmt: [CaseExpr] case ...
1038-
# 123| getValue: [MethodCall] call to expr
1039-
# 123| getReceiver: [Self, SelfVariableAccess] self
1040-
# 124| getBranch: [InClause] in ... then ...
1041-
# 124| getPattern: [FindPattern] [ *,...,* ]
1042-
# 124| getElement: [LocalVariableAccess] x
1043-
# 125| getBranch: [InClause] in ... then ...
1044-
# 125| getPattern: [FindPattern] [ *,...,* ]
1045-
# 125| getPrefixVariableAccess: [LocalVariableAccess] x
1046-
# 125| getElement: [IntegerLiteral] 1
1047-
# 125| getElement: [IntegerLiteral] 2
1048-
# 125| getSuffixVariableAccess: [LocalVariableAccess] y
1036+
# 118| getClass: [ConstantReadAccess] Foo
1037+
# 119| getBranch: [InClause] in ... then ...
1038+
# 119| getPattern: [ArrayPattern] [ ..., * ]
1039+
# 119| getClass: [ConstantReadAccess] Bar
1040+
# 120| getBranch: [InClause] in ... then ...
1041+
# 120| getPattern: [ArrayPattern] [ ..., * ]
1042+
# 120| getClass: [ConstantReadAccess] Bar
1043+
# 120| getPrefixElement/getSuffixElement: [LocalVariableAccess] a
1044+
# 120| getPrefixElement/getSuffixElement: [LocalVariableAccess] b
1045+
# 120| getRestVariableAccess: [LocalVariableAccess] c
1046+
# 120| getSuffixElement: [LocalVariableAccess] d
1047+
# 120| getSuffixElement: [LocalVariableAccess] e
1048+
# 125| getStmt: [CaseExpr] case ...
1049+
# 125| getValue: [MethodCall] call to expr
1050+
# 125| getReceiver: [Self, SelfVariableAccess] self
10491051
# 126| getBranch: [InClause] in ... then ...
10501052
# 126| getPattern: [FindPattern] [ *,...,* ]
1051-
# 126| getClass: [ConstantReadAccess] Bar
1052-
# 126| getScopeExpr: [ConstantReadAccess] Foo
1053-
# 126| getElement: [IntegerLiteral] 1
1053+
# 126| getElement: [LocalVariableAccess] x
10541054
# 127| getBranch: [InClause] in ... then ...
10551055
# 127| getPattern: [FindPattern] [ *,...,* ]
1056-
# 127| getClass: [ConstantReadAccess] Foo
1057-
# 127| getElement: [ConstantReadAccess] Bar
1058-
# 132| getStmt: [CaseExpr] case ...
1059-
# 132| getValue: [MethodCall] call to expr
1060-
# 132| getReceiver: [Self, SelfVariableAccess] self
1061-
# 133| getBranch: [InClause] in ... then ...
1062-
# 133| getPattern: [HashPattern] { ..., ** }
1063-
# 134| getBranch: [InClause] in ... then ...
1064-
# 134| getPattern: [HashPattern] { ..., ** }
1065-
# 134| getKey: [SymbolLiteral] :x
1056+
# 127| getPrefixVariableAccess: [LocalVariableAccess] x
1057+
# 127| getElement: [IntegerLiteral] 1
1058+
# 127| getElement: [IntegerLiteral] 2
1059+
# 127| getSuffixVariableAccess: [LocalVariableAccess] y
1060+
# 128| getBranch: [InClause] in ... then ...
1061+
# 128| getPattern: [FindPattern] [ *,...,* ]
1062+
# 128| getClass: [ConstantReadAccess] Bar
1063+
# 128| getScopeExpr: [ConstantReadAccess] Foo
1064+
# 128| getElement: [IntegerLiteral] 1
1065+
# 129| getBranch: [InClause] in ... then ...
1066+
# 129| getPattern: [FindPattern] [ *,...,* ]
1067+
# 129| getClass: [ConstantReadAccess] Foo
1068+
# 129| getElement: [ConstantReadAccess] Bar
1069+
# 134| getStmt: [CaseExpr] case ...
1070+
# 134| getValue: [MethodCall] call to expr
1071+
# 134| getReceiver: [Self, SelfVariableAccess] self
10661072
# 135| getBranch: [InClause] in ... then ...
10671073
# 135| getPattern: [HashPattern] { ..., ** }
1068-
# 135| getClass: [ConstantReadAccess] Bar
1069-
# 135| getScopeExpr: [ConstantReadAccess] Foo
1070-
# 135| getKey: [SymbolLiteral] :x
1071-
# 135| getValue: [IntegerLiteral] 1
10721074
# 136| getBranch: [InClause] in ... then ...
10731075
# 136| getPattern: [HashPattern] { ..., ** }
1074-
# 136| getClass: [ConstantReadAccess] Bar
1075-
# 136| getScopeExpr: [ConstantReadAccess] Foo
10761076
# 136| getKey: [SymbolLiteral] :x
1077-
# 136| getValue: [IntegerLiteral] 1
1078-
# 136| getKey: [SymbolLiteral] :a
1079-
# 136| getRestVariableAccess: [LocalVariableAccess] rest
10801077
# 137| getBranch: [InClause] in ... then ...
10811078
# 137| getPattern: [HashPattern] { ..., ** }
1082-
# 137| getClass: [ConstantReadAccess] Foo
1083-
# 137| getKey: [SymbolLiteral] :y
1079+
# 137| getClass: [ConstantReadAccess] Bar
1080+
# 137| getScopeExpr: [ConstantReadAccess] Foo
1081+
# 137| getKey: [SymbolLiteral] :x
1082+
# 137| getValue: [IntegerLiteral] 1
10841083
# 138| getBranch: [InClause] in ... then ...
10851084
# 138| getPattern: [HashPattern] { ..., ** }
10861085
# 138| getClass: [ConstantReadAccess] Bar
1086+
# 138| getScopeExpr: [ConstantReadAccess] Foo
1087+
# 138| getKey: [SymbolLiteral] :x
1088+
# 138| getValue: [IntegerLiteral] 1
1089+
# 138| getKey: [SymbolLiteral] :a
1090+
# 138| getRestVariableAccess: [LocalVariableAccess] rest
10871091
# 139| getBranch: [InClause] in ... then ...
10881092
# 139| getPattern: [HashPattern] { ..., ** }
1089-
# 139| getClass: [ConstantReadAccess] Bar
1090-
# 139| getKey: [SymbolLiteral] :a
1091-
# 139| getValue: [IntegerLiteral] 1
1093+
# 139| getClass: [ConstantReadAccess] Foo
1094+
# 139| getKey: [SymbolLiteral] :y
1095+
# 140| getBranch: [InClause] in ... then ...
1096+
# 140| getPattern: [HashPattern] { ..., ** }
1097+
# 140| getClass: [ConstantReadAccess] Bar
1098+
# 141| getBranch: [InClause] in ... then ...
1099+
# 141| getPattern: [HashPattern] { ..., ** }
1100+
# 141| getClass: [ConstantReadAccess] Bar
1101+
# 141| getKey: [SymbolLiteral] :a
1102+
# 141| getValue: [IntegerLiteral] 1
10921103
modules/classes.rb:
10931104
# 2| [Toplevel] classes.rb
10941105
# 3| getStmt: [ClassDeclaration] Foo

ruby/ql/test/library-tests/ast/ValueText.expected

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,21 @@
200200
| control/cases.rb:105:6:105:15 | :"foo bar" | foo bar |
201201
| control/cases.rb:106:7:106:7 | 5 | 5 |
202202
| control/cases.rb:106:12:106:13 | 10 | 10 |
203-
| control/cases.rb:125:11:125:11 | 1 | 1 |
204-
| control/cases.rb:125:14:125:14 | 2 | 2 |
205-
| control/cases.rb:126:18:126:18 | 1 | 1 |
206-
| control/cases.rb:134:7:134:7 | :x | x |
207-
| control/cases.rb:135:16:135:16 | :x | x |
208-
| control/cases.rb:135:18:135:18 | 1 | 1 |
209-
| control/cases.rb:136:16:136:16 | :x | x |
210-
| control/cases.rb:136:18:136:18 | 1 | 1 |
211-
| control/cases.rb:136:21:136:21 | :a | a |
212-
| control/cases.rb:137:11:137:11 | :y | y |
213-
| control/cases.rb:139:11:139:11 | :a | a |
214-
| control/cases.rb:139:14:139:14 | 1 | 1 |
203+
| control/cases.rb:107:7:107:7 | 1 | 1 |
204+
| control/cases.rb:108:7:108:7 | 0 | 0 |
205+
| control/cases.rb:108:11:108:12 | "" | |
206+
| control/cases.rb:127:11:127:11 | 1 | 1 |
207+
| control/cases.rb:127:14:127:14 | 2 | 2 |
208+
| control/cases.rb:128:18:128:18 | 1 | 1 |
209+
| control/cases.rb:136:7:136:7 | :x | x |
210+
| control/cases.rb:137:16:137:16 | :x | x |
211+
| control/cases.rb:137:18:137:18 | 1 | 1 |
212+
| control/cases.rb:138:16:138:16 | :x | x |
213+
| control/cases.rb:138:18:138:18 | 1 | 1 |
214+
| control/cases.rb:138:21:138:21 | :a | a |
215+
| control/cases.rb:139:11:139:11 | :y | y |
216+
| control/cases.rb:141:11:141:11 | :a | a |
217+
| control/cases.rb:141:14:141:14 | 1 | 1 |
215218
| control/conditionals.rb:2:5:2:5 | 0 | 0 |
216219
| control/conditionals.rb:3:5:3:5 | 0 | 0 |
217220
| control/conditionals.rb:4:5:4:5 | 0 | 0 |

0 commit comments

Comments
 (0)