Merge pull request #18142 from github/redsun82/swift-6-for-each-vars

Swift: extract variables as children of `ForEachStmt`
This commit is contained in:
Paolo Tranquilli
2024-12-04 11:08:35 +01:00
committed by GitHub
24 changed files with 161 additions and 14 deletions

View File

@@ -9,5 +9,6 @@ import codeql.swift.elements.expr.Expr
import codeql.swift.elements.stmt.LabeledStmt
import codeql.swift.elements.pattern.Pattern
import codeql.swift.elements.decl.PatternBindingDecl
import codeql.swift.elements.decl.VarDecl
final class ForEachStmt = Impl::ForEachStmt;

View File

@@ -3873,14 +3873,15 @@ private module Impl {
ForEachStmt e, int index, string partialPredicateCall
) {
exists(
int b, int bLabeledStmt, int n, int nPattern, int nWhere, int nIteratorVar, int nNextCall,
int nBody
int b, int bLabeledStmt, int n, int nVariable, int nPattern, int nWhere, int nIteratorVar,
int nNextCall, int nBody
|
b = 0 and
bLabeledStmt =
b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLabeledStmt(e, i, _)) | i) and
n = bLabeledStmt and
nPattern = n + 1 and
nVariable = n + 1 + max(int i | i = -1 or exists(e.getVariable(i)) | i) and
nPattern = nVariable + 1 and
nWhere = nPattern + 1 and
nIteratorVar = nWhere + 1 and
nNextCall = nIteratorVar + 1 and
@@ -3890,7 +3891,12 @@ private module Impl {
or
result = getImmediateChildOfLabeledStmt(e, index - b, partialPredicateCall)
or
index = n and result = e.getImmediatePattern() and partialPredicateCall = "Pattern()"
result = e.getVariable(index - n) and
partialPredicateCall = "Variable(" + (index - n).toString() + ")"
or
index = nVariable and
result = e.getImmediatePattern() and
partialPredicateCall = "Pattern()"
or
index = nPattern and result = e.getImmediateWhere() and partialPredicateCall = "Where()"
or

View File

@@ -3003,6 +3003,11 @@ module Raw {
class ForEachStmt extends @for_each_stmt, LabeledStmt {
override string toString() { result = "ForEachStmt" }
/**
* Gets the `index`th variable of this for each statement (0-based).
*/
VarDecl getVariable(int index) { for_each_stmt_variables(this, index, result) }
/**
* Gets the pattern of this for each statement.
*/

View File

@@ -11,6 +11,7 @@ import codeql.swift.elements.expr.Expr
import codeql.swift.elements.stmt.internal.LabeledStmtImpl::Impl as LabeledStmtImpl
import codeql.swift.elements.pattern.Pattern
import codeql.swift.elements.decl.PatternBindingDecl
import codeql.swift.elements.decl.VarDecl
/**
* INTERNAL: This module contains the fully generated definition of `ForEachStmt` and should not
@@ -24,6 +25,26 @@ module Generated {
class ForEachStmt extends Synth::TForEachStmt, LabeledStmtImpl::LabeledStmt {
override string getAPrimaryQlClass() { result = "ForEachStmt" }
/**
* Gets the `index`th variable of this for each statement (0-based).
*/
VarDecl getVariable(int index) {
result =
Synth::convertVarDeclFromRaw(Synth::convertForEachStmtToRaw(this)
.(Raw::ForEachStmt)
.getVariable(index))
}
/**
* Gets any of the variables of this for each statement.
*/
final VarDecl getAVariable() { result = this.getVariable(_) }
/**
* Gets the number of variables of this for each statement.
*/
final int getNumberOfVariables() { result = count(int i | exists(this.getVariable(i))) }
/**
* Gets the pattern of this for each statement.
*

View File

@@ -2019,6 +2019,13 @@ for_each_stmts( //dir=stmt
int body: @brace_stmt_or_none ref
);
#keyset[id, index]
for_each_stmt_variables( //dir=stmt
int id: @for_each_stmt ref,
int index: int ref,
int variable: @var_decl_or_none ref
);
#keyset[id]
for_each_stmt_wheres( //dir=stmt
int id: @for_each_stmt ref,