Skip to content

Commit dfcf4c9

Browse files
authored
Merge pull request #199 from github/hvitved/splat-expr
Rename `(Hash)SplatArgument` to `(Hash)SplatExpr` and make them `UnaryOperation`s
2 parents 2094aa9 + 1007f2a commit dfcf4c9

17 files changed

Lines changed: 629 additions & 635 deletions

File tree

ql/src/codeql_ruby/ast/Call.qll

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -192,65 +192,3 @@ class BlockArgument extends Expr, TBlockArgument {
192192
pred = "getValue" and result = this.getValue()
193193
}
194194
}
195-
196-
/**
197-
* A splat argument in a method call.
198-
* ```rb
199-
* foo(*args)
200-
* ```
201-
*/
202-
class SplatArgument extends Expr, TSplatArgument {
203-
private Generated::SplatArgument g;
204-
205-
SplatArgument() { this = TSplatArgument(g) }
206-
207-
final override string getAPrimaryQlClass() { result = "SplatArgument" }
208-
209-
/**
210-
* Gets the underlying expression. In the following example, the result is
211-
* the `Expr` for `bar`:
212-
* ```rb
213-
* foo(*bar)
214-
* ```
215-
*/
216-
final Expr getValue() { toGenerated(result) = g.getChild() }
217-
218-
final override string toString() { result = "*..." }
219-
220-
final override AstNode getAChild(string pred) {
221-
result = super.getAChild(pred)
222-
or
223-
pred = "getValue" and result = this.getValue()
224-
}
225-
}
226-
227-
/**
228-
* A hash-splat (or 'double-splat') argument in a method call.
229-
* ```rb
230-
* foo(**options)
231-
* ```
232-
*/
233-
class HashSplatArgument extends Expr, THashSplatArgument {
234-
private Generated::HashSplatArgument g;
235-
236-
HashSplatArgument() { this = THashSplatArgument(g) }
237-
238-
final override string getAPrimaryQlClass() { result = "HashSplatArgument" }
239-
240-
/**
241-
* Gets the underlying expression. In the following example, the result is
242-
* the `Expr` for `bar`:
243-
* ```rb
244-
* foo(**bar)
245-
* ```
246-
*/
247-
final Expr getValue() { toGenerated(result) = g.getChild() }
248-
249-
final override string toString() { result = "**..." }
250-
251-
final override AstNode getAChild(string pred) {
252-
result = super.getAChild(pred)
253-
or
254-
pred = "getValue" and result = this.getValue()
255-
}
256-
}

ql/src/codeql_ruby/ast/Literal.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ class HashLiteral extends Literal, THashLiteral {
717717
* Gets the `n`th element in this array literal.
718718
*
719719
* In the following example, the 0th element is a `Pair`, and the 1st element
720-
* is a `HashSplatArgument`.
720+
* is a `HashSplatExpr`.
721721
*
722722
* ```rb
723723
* { foo: 123, **bar }

ql/src/codeql_ruby/ast/Operation.qll

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,8 @@ class Operation extends Expr, TOperation {
2424

2525
/** A unary operation. */
2626
class UnaryOperation extends Operation, TUnaryOperation {
27-
private Generated::Unary g;
28-
29-
UnaryOperation() { g = toGenerated(this) }
30-
3127
/** Gets the operand of this unary operation. */
32-
final Expr getOperand() { toGenerated(result) = g.getOperand() }
33-
34-
final override string getOperator() { result = g.getOperator() }
28+
Expr getOperand() { none() }
3529

3630
final override Expr getAnOperand() { result = this.getOperand() }
3731

@@ -44,8 +38,18 @@ class UnaryOperation extends Operation, TUnaryOperation {
4438
final override string toString() { result = this.getOperator() + " ..." }
4539
}
4640

41+
private class UnaryOperationGenerated extends UnaryOperation, TUnaryOperation {
42+
private Generated::Unary g;
43+
44+
UnaryOperationGenerated() { g = toGenerated(this) }
45+
46+
final override Expr getOperand() { toGenerated(result) = g.getOperand() }
47+
48+
final override string getOperator() { result = g.getOperator() }
49+
}
50+
4751
/** A unary logical operation. */
48-
class UnaryLogicalOperation extends UnaryOperation, TUnaryLogicalOperation { }
52+
class UnaryLogicalOperation extends UnaryOperationGenerated, TUnaryLogicalOperation { }
4953

5054
/**
5155
* A logical NOT operation, using either `!` or `not`.
@@ -59,7 +63,7 @@ class NotExpr extends UnaryLogicalOperation, TNotExpr {
5963
}
6064

6165
/** A unary arithmetic operation. */
62-
class UnaryArithmeticOperation extends UnaryOperation, TUnaryArithmeticOperation { }
66+
class UnaryArithmeticOperation extends UnaryOperationGenerated, TUnaryArithmeticOperation { }
6367

6468
/**
6569
* A unary plus expression.
@@ -81,6 +85,42 @@ class UnaryMinusExpr extends UnaryArithmeticOperation, TUnaryMinusExpr {
8185
final override string getAPrimaryQlClass() { result = "UnaryMinusExpr" }
8286
}
8387

88+
/**
89+
* A splat expression.
90+
* ```rb
91+
* foo(*args)
92+
* ```
93+
*/
94+
class SplatExpr extends UnaryOperation, TSplatArgument {
95+
private Generated::SplatArgument g;
96+
97+
SplatExpr() { this = TSplatArgument(g) }
98+
99+
final override Expr getOperand() { toGenerated(result) = g.getChild() }
100+
101+
final override string getOperator() { result = "*" }
102+
103+
final override string getAPrimaryQlClass() { result = "SplatExpr" }
104+
}
105+
106+
/**
107+
* A hash-splat (or 'double-splat') expression.
108+
* ```rb
109+
* foo(**options)
110+
* ```
111+
*/
112+
class HashSplatExpr extends UnaryOperation, THashSplatArgument {
113+
private Generated::HashSplatArgument g;
114+
115+
HashSplatExpr() { this = THashSplatArgument(g) }
116+
117+
final override Expr getOperand() { toGenerated(result) = g.getChild() }
118+
119+
final override string getOperator() { result = "**" }
120+
121+
final override string getAPrimaryQlClass() { result = "HashSplatExpr" }
122+
}
123+
84124
/** A unary bitwise operation. */
85125
class UnaryBitwiseOperation extends UnaryOperation, TUnaryBitwiseOperation { }
86126

ql/src/codeql_ruby/ast/internal/AST.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,8 @@ class TNamespace = TClassDeclaration or TModuleDeclaration;
585585
class TOperation = TUnaryOperation or TBinaryOperation or TAssignment;
586586

587587
class TUnaryOperation =
588-
TUnaryLogicalOperation or TUnaryArithmeticOperation or TUnaryBitwiseOperation or TDefinedExpr;
588+
TUnaryLogicalOperation or TUnaryArithmeticOperation or TUnaryBitwiseOperation or TDefinedExpr or
589+
TSplatArgument or THashSplatArgument;
589590

590591
class TUnaryLogicalOperation = TNotExpr;
591592

ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -853,10 +853,6 @@ module Trees {
853853
final override ControlFlowTree getChildNode(int i) { result = this.getElement(i) }
854854
}
855855

856-
private class HashSplatArgumentTree extends StandardPostOrderTree, HashSplatArgument {
857-
final override ControlFlowTree getChildNode(int i) { result = this.getValue() and i = 0 }
858-
}
859-
860856
private class HashSplatParameterTree extends NonDefaultValueParameterTree, HashSplatParameter { }
861857

862858
private class HereDocTree extends StandardPreOrderTree, HereDoc {
@@ -1172,10 +1168,6 @@ module Trees {
11721168
}
11731169
}
11741170

1175-
private class SplatArgumentTree extends StandardPostOrderTree, SplatArgument {
1176-
final override ControlFlowTree getChildNode(int i) { result = this.getValue() and i = 0 }
1177-
}
1178-
11791171
private class SplatParameterTree extends NonDefaultValueParameterTree, SplatParameter { }
11801172

11811173
class StmtSequenceTree extends PostOrderTree, StmtSequence {

0 commit comments

Comments
 (0)