Merge branch 'main' into rails/render_locals_shared

This commit is contained in:
Alex Ford
2023-01-23 10:00:22 +00:00
committed by GitHub
199 changed files with 175567 additions and 5332 deletions

View File

@@ -1,3 +1,7 @@
## 0.5.1
No user-facing changes.
## 0.5.0
### Major Analysis Improvements

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Ruby 3.2: anonymous rest and keyword rest arguments can now be passed as arguments, instead of just used in method parameters.

View File

@@ -0,0 +1,3 @@
## 0.5.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.0
lastReleaseVersion: 0.5.1

View File

@@ -181,7 +181,10 @@ class HashSplatParameter extends NamedParameter, THashSplatParameter {
final override string getAPrimaryQlClass() { result = "HashSplatParameter" }
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()
@@ -307,7 +310,10 @@ class SplatParameter extends NamedParameter, TSplatParameter {
final override string getAPrimaryQlClass() { result = "SplatParameter" }
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()

View File

@@ -36,7 +36,7 @@ class LocalVariable extends Variable, TLocalVariable {
/** Gets the access where this local variable is first introduced. */
VariableAccess getDefiningAccess() {
result = this.(LocalVariableReal).getDefiningAccessImpl() or
synthChild(any(BlockParameter p | this = p.getVariable()), 0, result)
synthChild(any(NamedParameter p | this = p.getVariable()), 0, result)
}
/**
@@ -120,7 +120,7 @@ class VariableAccess extends Expr instanceof VariableAccessImpl {
or
this = any(HashPattern p).getValue(_)
or
synthChild(any(BlockParameter p), 0, this)
synthChild(any(NamedParameter p), 0, this)
}
}

View File

@@ -42,7 +42,10 @@ class SplatExprReal extends UnaryOperationImpl, TSplatExprReal {
final override string getOperatorImpl() { result = "*" }
final override Expr getOperandImpl() { toGenerated(result) = g.getChild() }
final override Expr getOperandImpl() {
toGenerated(result) = g.getChild() or
synthChild(this, 0, result)
}
}
class SplatExprSynth extends UnaryOperationImpl, TSplatExprSynth {
@@ -56,7 +59,10 @@ class HashSplatExprImpl extends UnaryOperationImpl, THashSplatExpr {
HashSplatExprImpl() { this = THashSplatExpr(g) }
final override Expr getOperandImpl() { toGenerated(result) = g.getChild() }
final override Expr getOperandImpl() {
toGenerated(result) = g.getChild() or
synthChild(this, 0, result)
}
final override string getOperatorImpl() { result = "**" }
}

View File

@@ -1317,46 +1317,62 @@ private module ImplicitHashValueSynthesis {
/**
* ```rb
* def foo(&)
* bar(&)
* def foo(*, **, &)
* bar(*, **, &)
* end
* ```
* desugars to,
* ```rb
* def foo(&__synth_0)
* bar(&__synth_0)
* def foo(*__synth_0, **__synth_1, &__synth_2)
* bar(*__synth_0, **__synth_1, &__synth_2)
* end
* ```
*/
private module AnonymousBlockParameterSynth {
private BlockParameter anonymousBlockParameter() {
private module AnonymousParameterSynth {
private class AnonymousParameter = TBlockParameter or THashSplatParameter or TSplatParameter;
private class AnonymousArgument = TBlockArgument or THashSplatExpr or TSplatExpr;
private AnonymousParameter anonymousParameter() {
exists(Ruby::BlockParameter p | not exists(p.getName()) and toGenerated(result) = p)
or
exists(Ruby::SplatParameter p | not exists(p.getName()) and toGenerated(result) = p)
or
exists(Ruby::HashSplatParameter p | not exists(p.getName()) and toGenerated(result) = p)
}
private BlockArgument anonymousBlockArgument() {
private AnonymousArgument anonymousArgument() {
exists(Ruby::BlockArgument p | not exists(p.getChild()) and toGenerated(result) = p)
or
exists(Ruby::SplatArgument p | not exists(p.getChild()) and toGenerated(result) = p)
or
exists(Ruby::HashSplatArgument p | not exists(p.getChild()) and toGenerated(result) = p)
}
private class AnonymousBlockParameterSynthesis extends Synthesis {
private class AnonymousParameterSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child) {
i = 0 and
parent = anonymousBlockParameter() and
parent = anonymousParameter() and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(parent, 0)))
}
final override predicate localVariable(AstNode n, int i) {
n = anonymousBlockParameter() and i = 0
}
final override predicate localVariable(AstNode n, int i) { n = anonymousParameter() and i = 0 }
}
private class AnonymousBlockArgumentSynthesis extends Synthesis {
private class AnonymousArgumentSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child) {
i = 0 and
parent = anonymousBlockArgument() and
exists(BlockParameter param |
param = anonymousBlockParameter() and
parent = anonymousArgument() and
exists(AnonymousParameter param |
param = anonymousParameter() and
scopeOf(toGenerated(parent)).getEnclosingMethod() = scopeOf(toGenerated(param)) and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0)))
|
param instanceof TBlockParameter and parent instanceof TBlockArgument
or
param instanceof TSplatParameter and parent instanceof TSplatExpr
or
param instanceof THashSplatParameter and parent instanceof THashSplatExpr
)
}
}

View File

@@ -875,10 +875,10 @@ module Ruby {
final override string getAPrimaryQlClass() { result = "HashSplatArgument" }
/** Gets the child of this node. */
final UnderscoreArg getChild() { ruby_hash_splat_argument_def(this, result) }
final UnderscoreArg getChild() { ruby_hash_splat_argument_child(this, result) }
/** Gets a field or child node of this node. */
final override AstNode getAFieldOrChild() { ruby_hash_splat_argument_def(this, result) }
final override AstNode getAFieldOrChild() { ruby_hash_splat_argument_child(this, result) }
}
/** A class representing `hash_splat_nil` tokens. */
@@ -1572,10 +1572,10 @@ module Ruby {
final override string getAPrimaryQlClass() { result = "SplatArgument" }
/** Gets the child of this node. */
final UnderscoreArg getChild() { ruby_splat_argument_def(this, result) }
final UnderscoreArg getChild() { ruby_splat_argument_child(this, result) }
/** Gets a field or child node of this node. */
final override AstNode getAFieldOrChild() { ruby_splat_argument_def(this, result) }
final override AstNode getAFieldOrChild() { ruby_splat_argument_child(this, result) }
}
/** A class representing `splat_parameter` nodes. */

View File

@@ -139,7 +139,7 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari
DataFlow::ParameterNode getParameter(string s) {
exists(ParameterPosition pos |
DataFlowImplCommon::parameterNode(result, TLibraryCallable(this), pos) and
s = getParameterPositionCsv(pos)
s = getParameterPosition(pos)
)
}
}

View File

@@ -39,6 +39,11 @@ module Public {
)
or
exists(ReturnKind rk | this = TReturnSummaryComponent(rk) and result = "return (" + rk + ")")
or
exists(SummaryComponent::SyntheticGlobal sg |
this = TSyntheticGlobalSummaryComponent(sg) and
result = "synthetic global (" + sg + ")"
)
}
}
@@ -159,24 +164,24 @@ module Public {
SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) }
}
private predicate noComponentSpecificCsv(SummaryComponent sc) {
not exists(getComponentSpecificCsv(sc))
private predicate noComponentSpecific(SummaryComponent sc) {
not exists(getComponentSpecific(sc))
}
/** Gets a textual representation of this component used for flow summaries. */
private string getComponentCsv(SummaryComponent sc) {
result = getComponentSpecificCsv(sc)
private string getComponent(SummaryComponent sc) {
result = getComponentSpecific(sc)
or
noComponentSpecificCsv(sc) and
noComponentSpecific(sc) and
(
exists(ArgumentPosition pos |
sc = TParameterSummaryComponent(pos) and
result = "Parameter[" + getArgumentPositionCsv(pos) + "]"
result = "Parameter[" + getArgumentPosition(pos) + "]"
)
or
exists(ParameterPosition pos |
sc = TArgumentSummaryComponent(pos) and
result = "Argument[" + getParameterPositionCsv(pos) + "]"
result = "Argument[" + getParameterPosition(pos) + "]"
)
or
sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue"
@@ -184,16 +189,16 @@ module Public {
}
/** Gets a textual representation of this stack used for flow summaries. */
string getComponentStackCsv(SummaryComponentStack stack) {
string getComponentStack(SummaryComponentStack stack) {
exists(SummaryComponent head, SummaryComponentStack tail |
head = stack.head() and
tail = stack.tail() and
result = getComponentStackCsv(tail) + "." + getComponentCsv(head)
result = getComponentStack(tail) + "." + getComponent(head)
)
or
exists(SummaryComponent c |
stack = TSingletonSummaryComponentStack(c) and
result = getComponentCsv(c)
result = getComponent(c)
)
}
@@ -1217,8 +1222,8 @@ module Private {
c.relevantSummary(input, output, preservesValue) and
csv =
c.getCallableCsv() // Callable information
+ getComponentStackCsv(input) + ";" // input
+ getComponentStackCsv(output) + ";" // output
+ getComponentStack(input) + ";" // input
+ getComponentStack(output) + ";" // output
+ renderKind(preservesValue) + ";" // kind
+ renderProvenance(c) // provenance
)

View File

@@ -139,10 +139,10 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
}
/** Gets the textual representation of a summary component in the format used for flow summaries. */
string getComponentSpecificCsv(SummaryComponent sc) { none() }
string getComponentSpecific(SummaryComponent sc) { none() }
/** Gets the textual representation of a parameter position in the format used for flow summaries. */
string getParameterPositionCsv(ParameterPosition pos) {
string getParameterPosition(ParameterPosition pos) {
exists(int i |
pos.isPositional(i) and
result = i.toString()
@@ -172,7 +172,7 @@ string getParameterPositionCsv(ParameterPosition pos) {
}
/** Gets the textual representation of an argument position in the format used for flow summaries. */
string getArgumentPositionCsv(ArgumentPosition pos) {
string getArgumentPosition(ArgumentPosition pos) {
pos.isSelf() and result = "self"
or
pos.isBlock() and result = "block"

View File

@@ -1,5 +1,5 @@
name: codeql/ruby-all
version: 0.5.1-dev
version: 0.5.2-dev
groups: ruby
extractor: ruby
dbscheme: ruby.dbscheme

View File

@@ -661,9 +661,13 @@ ruby_hash_pattern_def(
unique int id: @ruby_hash_pattern
);
ruby_hash_splat_argument_child(
unique int ruby_hash_splat_argument: @ruby_hash_splat_argument ref,
unique int child: @ruby_underscore_arg ref
);
ruby_hash_splat_argument_def(
unique int id: @ruby_hash_splat_argument,
int child: @ruby_underscore_arg ref
unique int id: @ruby_hash_splat_argument
);
ruby_hash_splat_parameter_name(
@@ -1112,9 +1116,13 @@ ruby_singleton_method_def(
int object: @ruby_singleton_method_object_type ref
);
ruby_splat_argument_child(
unique int ruby_splat_argument: @ruby_splat_argument ref,
unique int child: @ruby_underscore_arg ref
);
ruby_splat_argument_def(
unique int id: @ruby_splat_argument,
int child: @ruby_underscore_arg ref
unique int id: @ruby_splat_argument
);
ruby_splat_parameter_name(

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
description: Update grammar
compatibility: full
ruby_splat_argument_def.rel: reorder ruby_splat_argument_def.rel ( int id, int child) id
ruby_splat_argument_child.rel: reorder ruby_splat_argument_def.rel ( int id, int child) id child
ruby_hash_splat_argument_def.rel: reorder ruby_hash_splat_argument_def.rel ( int id, int child) id
ruby_hash_splat_argument_child.rel: reorder ruby_hash_splat_argument_def.rel ( int id, int child) id child