mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
Ruby: support anonymous block parameters/arguments
This commit is contained in:
@@ -187,7 +187,10 @@ class BlockArgument extends Expr, TBlockArgument {
|
||||
* foo(&bar)
|
||||
* ```
|
||||
*/
|
||||
final Expr getValue() { toGenerated(result) = g.getChild() }
|
||||
final Expr getValue() {
|
||||
toGenerated(result) = g.getChild() or
|
||||
synthChild(this, 0, result)
|
||||
}
|
||||
|
||||
final override string toString() { result = "&..." }
|
||||
|
||||
|
||||
@@ -148,11 +148,19 @@ class BlockParameter extends NamedParameter, TBlockParameter {
|
||||
|
||||
BlockParameter() { this = TBlockParameter(g) }
|
||||
|
||||
/** Gets the name of this parameter, if any. */
|
||||
final override string getName() { result = g.getName().getValue() }
|
||||
|
||||
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
|
||||
final override LocalVariable getVariable() {
|
||||
result = TLocalVariableReal(_, _, g.getName()) or
|
||||
result = TLocalVariableSynth(this, 0)
|
||||
}
|
||||
|
||||
final override string toString() { result = "&" + this.getName() }
|
||||
final override string toString() {
|
||||
result = "&" + this.getName()
|
||||
or
|
||||
not exists(this.getName()) and result = "&"
|
||||
}
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "BlockParameter" }
|
||||
}
|
||||
|
||||
@@ -35,7 +35,10 @@ class LocalVariable extends Variable, TLocalVariable {
|
||||
override LocalVariableAccess getAnAccess() { result.getVariable() = this }
|
||||
|
||||
/** Gets the access where this local variable is first introduced. */
|
||||
VariableAccess getDefiningAccess() { result = this.(LocalVariableReal).getDefiningAccessImpl() }
|
||||
VariableAccess getDefiningAccess() {
|
||||
result = this.(LocalVariableReal).getDefiningAccessImpl() or
|
||||
synthChild(any(BlockParameter p | this = p.getVariable()), 0, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this variable is captured. For example in
|
||||
@@ -117,6 +120,8 @@ class VariableAccess extends Expr instanceof VariableAccessImpl {
|
||||
this = any(SimpleParameterSynthImpl p).getDefininingAccess()
|
||||
or
|
||||
this = any(HashPattern p).getValue(_)
|
||||
or
|
||||
synthChild(any(BlockParameter p), 0, this)
|
||||
}
|
||||
|
||||
final override string toString() { result = VariableAccessImpl.super.toString() }
|
||||
|
||||
@@ -996,3 +996,37 @@ private module ImplicitHashValueSynthesis {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private module AnonymousBlockParameterSynth {
|
||||
private BlockParameter anonymousBlockParameter() {
|
||||
exists(Ruby::BlockParameter p | not exists(p.getName()) and toGenerated(result) = p)
|
||||
}
|
||||
|
||||
private BlockArgument anonymousBlockArgument() {
|
||||
exists(Ruby::BlockArgument p | not exists(p.getChild()) and toGenerated(result) = p)
|
||||
}
|
||||
|
||||
private class AnonymousBlockParameterSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
i = 0 and
|
||||
parent = anonymousBlockParameter() and
|
||||
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(parent, 0)))
|
||||
}
|
||||
|
||||
final override predicate localVariable(AstNode n, int i) {
|
||||
n = anonymousBlockParameter() and i = 0
|
||||
}
|
||||
}
|
||||
|
||||
private class AnonymousBlockArgumentSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
i = 0 and
|
||||
parent = anonymousBlockArgument() and
|
||||
exists(BlockParameter param |
|
||||
param = anonymousBlockParameter() and
|
||||
scopeOf(toGenerated(parent)).getEnclosingMethod() = scopeOf(toGenerated(param)) and
|
||||
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0)))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +457,9 @@ calls/calls.rb:
|
||||
# 267| getArgument: [BlockArgument] &...
|
||||
# 267| getValue: [MethodCall] call to bar
|
||||
# 267| getReceiver: [ConstantReadAccess] X
|
||||
# 268| getStmt: [MethodCall] call to foo
|
||||
# 268| getReceiver: [Self, SelfVariableAccess] self
|
||||
# 268| getArgument: [BlockArgument] &...
|
||||
# 270| getStmt: [MethodCall] call to foo
|
||||
# 270| getReceiver: [Self, SelfVariableAccess] self
|
||||
# 270| getArgument: [SplatExpr] * ...
|
||||
@@ -2694,6 +2697,19 @@ params/params.rb:
|
||||
# 77| getParameter: [SimpleParameter] val
|
||||
# 77| getDefiningAccess: [LocalVariableAccess] val
|
||||
# 77| getParameter: [HashSplatNilParameter] **nil
|
||||
# 81| getStmt: [Method] anonymous_block_parameter
|
||||
# 81| getParameter: [SimpleParameter] array
|
||||
# 81| getDefiningAccess: [LocalVariableAccess] array
|
||||
# 81| getParameter: [BlockParameter] &
|
||||
# 81| getDefiningAccess: [LocalVariableAccess] __synth__0
|
||||
# 82| getStmt: [MethodCall] call to proc
|
||||
# 82| getReceiver: [Self, SelfVariableAccess] self
|
||||
# 82| getArgument: [BlockArgument] &...
|
||||
# 82| getValue: [LocalVariableAccess] __synth__0
|
||||
# 83| getStmt: [MethodCall] call to each
|
||||
# 83| getReceiver: [LocalVariableAccess] array
|
||||
# 83| getArgument: [BlockArgument] &...
|
||||
# 83| getValue: [LocalVariableAccess] __synth__0
|
||||
erb/template.html.erb:
|
||||
# 19| [Toplevel] template.html.erb
|
||||
# 19| getStmt: [StringLiteral] "hello world"
|
||||
|
||||
@@ -26,6 +26,7 @@ callsWithArguments
|
||||
| calls.rb:249:1:249:32 | call to [] | [] | 1 | calls.rb:249:15:249:30 | Pair |
|
||||
| calls.rb:266:1:266:9 | call to foo | foo | 0 | calls.rb:266:5:266:8 | &... |
|
||||
| calls.rb:267:1:267:12 | call to foo | foo | 0 | calls.rb:267:5:267:11 | &... |
|
||||
| calls.rb:268:1:268:6 | call to foo | foo | 0 | calls.rb:268:5:268:5 | &... |
|
||||
| calls.rb:270:1:270:9 | call to foo | foo | 0 | calls.rb:270:5:270:8 | * ... |
|
||||
| calls.rb:271:1:271:12 | call to foo | foo | 0 | calls.rb:271:5:271:11 | * ... |
|
||||
| calls.rb:274:1:274:10 | call to foo | foo | 0 | calls.rb:274:5:274:9 | ** ... |
|
||||
@@ -267,6 +268,7 @@ callsWithReceiver
|
||||
| calls.rb:266:6:266:8 | call to bar | calls.rb:266:6:266:8 | self |
|
||||
| calls.rb:267:1:267:12 | call to foo | calls.rb:267:1:267:12 | self |
|
||||
| calls.rb:267:6:267:11 | call to bar | calls.rb:267:6:267:6 | X |
|
||||
| calls.rb:268:1:268:6 | call to foo | calls.rb:268:1:268:6 | self |
|
||||
| calls.rb:270:1:270:9 | call to foo | calls.rb:270:1:270:9 | self |
|
||||
| calls.rb:270:5:270:8 | * ... | calls.rb:270:6:270:8 | call to bar |
|
||||
| calls.rb:270:6:270:8 | call to bar | calls.rb:270:6:270:8 | self |
|
||||
|
||||
@@ -265,7 +265,7 @@ X::foo rescue X::bar
|
||||
# block argument
|
||||
foo(&bar)
|
||||
foo(&X::bar)
|
||||
|
||||
foo(&)
|
||||
# splat argument
|
||||
foo(*bar)
|
||||
foo(*X::bar)
|
||||
|
||||
@@ -35,6 +35,7 @@ idParams
|
||||
| params.rb:70:48:70:48 | c | c |
|
||||
| params.rb:73:27:73:32 | wibble | wibble |
|
||||
| params.rb:77:16:77:18 | val | val |
|
||||
| params.rb:81:31:81:35 | array | array |
|
||||
blockParams
|
||||
| params.rb:46:28:46:33 | &block | block |
|
||||
| params.rb:62:29:62:34 | &block | block |
|
||||
@@ -87,6 +88,8 @@ paramsInMethods
|
||||
| params.rb:62:1:64:3 | use_block_with_optional | 0 | params.rb:62:29:62:34 | &block | BlockParameter |
|
||||
| params.rb:73:1:74:3 | method_with_nil_splat | 0 | params.rb:73:27:73:32 | wibble | SimpleParameter |
|
||||
| params.rb:73:1:74:3 | method_with_nil_splat | 1 | params.rb:73:35:73:39 | **nil | HashSplatNilParameter |
|
||||
| params.rb:81:1:84:3 | anonymous_block_parameter | 0 | params.rb:81:31:81:35 | array | SimpleParameter |
|
||||
| params.rb:81:1:84:3 | anonymous_block_parameter | 1 | params.rb:81:38:81:38 | & | BlockParameter |
|
||||
paramsInBlocks
|
||||
| params.rb:9:11:11:3 | do ... end | 0 | params.rb:9:15:9:17 | key | SimpleParameter |
|
||||
| params.rb:9:11:11:3 | do ... end | 1 | params.rb:9:20:9:24 | value | SimpleParameter |
|
||||
@@ -157,3 +160,5 @@ params
|
||||
| params.rb:73:35:73:39 | **nil | 1 | HashSplatNilParameter |
|
||||
| params.rb:77:16:77:18 | val | 0 | SimpleParameter |
|
||||
| params.rb:77:21:77:25 | **nil | 1 | HashSplatNilParameter |
|
||||
| params.rb:81:31:81:35 | array | 0 | SimpleParameter |
|
||||
| params.rb:81:38:81:38 | & | 1 | BlockParameter |
|
||||
|
||||
@@ -77,3 +77,8 @@ end
|
||||
array.each do |val, **nil|
|
||||
end
|
||||
|
||||
# Anonymous block parameter
|
||||
def anonymous_block_parameter(array, &)
|
||||
proc(&)
|
||||
array.each(&)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user