Swift: extract variables as children of ForEachStmt

This commit is contained in:
Paolo Tranquilli
2024-11-28 10:52:17 +01:00
parent 8bcc5f4bf8
commit 814218c7a8
24 changed files with 161 additions and 14 deletions

View File

@@ -77,6 +77,17 @@ codeql::ForEachStmt StmtTranslator::translateForEachStmt(const swift::ForEachStm
entry.iteratorVar = dispatcher.fetchLabel(stmt.getIteratorVar());
entry.where = dispatcher.fetchOptionalLabel(stmt.getWhere());
entry.nextCall = dispatcher.fetchOptionalLabel(stmt.getNextCall());
auto add_variable = [&](swift::VarDecl* var) {
entry.variables.push_back(dispatcher.fetchLabel(var));
};
if (auto pattern = stmt.getPattern()) {
pattern->forEachVariable(add_variable);
}
if (auto iteratorVar = stmt.getIteratorVar()) {
for (auto i = 0u; i < iteratorVar->getNumPatternEntries(); ++i) {
iteratorVar->getPattern(i)->forEachVariable(add_variable);
}
}
return entry;
}

View File

@@ -463,7 +463,7 @@ lib/codeql/swift/elements/stmt/DoCatchStmt.qll a4639b674880e85d15ef4077370eb2ff2
lib/codeql/swift/elements/stmt/DoStmt.qll 2117eb68a82bde082fc06b44d7bdabd6d773abda95555b81e92f6d409a93b462 c5ec1fba5ba562629863ac6d1a15f9bbd8dce9f59326f580997352b47f9f2a90
lib/codeql/swift/elements/stmt/FailStmt.qll 0dc6467b2e6b4852ad6054122601c445f31c5e9c9837ceac132849a37119f7b5 0fac97257b7b2e453c484ca0212e61e655e2b2fa456f030ce159806dee048909
lib/codeql/swift/elements/stmt/FallthroughStmt.qll f7bfad479ed2f3011a4e8ebe3e4a7f3e6b7f832518ac4d2401122b8be32bbc91 2daabb70b723d9f95d4b120ec2774df8c2ba315f9b17f944a65d306f71c0a70f
lib/codeql/swift/elements/stmt/ForEachStmt.qll 70fb1f12a95c14eebd9cb30c53898ca044843ed6b14569f54e52697af7b39f59 6483f1941b7a97f4cc919c578b25da69b783dc9b3ebe4a2839702553ff2f64fb
lib/codeql/swift/elements/stmt/ForEachStmt.qll 328f1036257affc8b4d0d34767d059a33eca599fe7fd69ce4ac9824d3985143c c9a79da4742b8dac82c2760e0c15809dcc237b09603798b9c8368f02e20c5138
lib/codeql/swift/elements/stmt/GuardStmt.qll 69d3a945ec1d7bad4d9157656c5a2388584afa013771e6657313e39b28284b4a 50812bd09f77d8aba1071f03f073bed8951b1b9bb940b424c91f7f10095333cd
lib/codeql/swift/elements/stmt/IfStmt.qll f60fb6be6f900c9e7c1a7ae84f0886f6fd5e70cbcc6c77c78d70ed2a62de77a9 a97ae07ef314b199baafa47af4cdc302ebf2f72205a14a28fdfc7db5ce4cfd47
lib/codeql/swift/elements/stmt/LabeledConditionalStmt.qll 64e4b4bedfc1fe74a7685213b22cb43098f669ec2c2947d9096a73e1e90104f3 28459d17878789184c8833eb202cb736ea7f267d728790561b57f60b4b9a2ce9
@@ -709,10 +709,10 @@ lib/codeql/swift/generated/Locatable.qll 1d37fa20de71c0b9986bfd7a7c0cb82ab7bf3fd
lib/codeql/swift/generated/Location.qll 5e20316c3e480ddfe632b7e88e016c19f10a67df1f6ae9c8f128755a6907d6f5 5a0af2d070bcb2ed53d6d0282bf9c60dc64c2dce89c21fdd485e9c7893c1c8fa
lib/codeql/swift/generated/MacroRole.qll 0d8fa6b0b6e2045d9097a87d53888cae2ea5371b2fa7d140341cf206f575b556 ea3b8a7c0a88851809f9a5a5aa80b0d2da3c4779bb29044cdba2b60246a2722c
lib/codeql/swift/generated/OtherAvailabilitySpec.qll d9feaa2a71acff3184ca389045b0a49d09156210df0e034923d715b432ad594b 046737621a8bcf69bf805afb0cff476bd15259f12f0d77fce3206dd01b31518f
lib/codeql/swift/generated/ParentChild.qll d1814f2bad4c2ba9242ce49fe6fb8564ac99fc1fd3a7d12aa55e5c6dd7bb529b 1a2075b731d07a5e3c6a69d001796c8de925069d839671a294c9cba6c3db724a
lib/codeql/swift/generated/ParentChild.qll b65c29ba8c3e13baac44a32d2521a11f07aeb7d33415aa9a91a7f6255a744415 0fe73d06c96194d5a0da19c9348a46d9f8fbf630fee5de3dc96e997c595c362e
lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll dc17b49a90a18a8f7607adf2433bc8f0c194fa3e803aa3822f809d4d4fbd6793 be48ea9f8ae17354c8508aaed24337a9e57ce01f288fece3dcecd99776cabcec
lib/codeql/swift/generated/PureSynthConstructors.qll bc31a6c4d142fa3fbdcae69d5ba6f1cec00eb9ad92b46c8d7b91ebfa7ef6c1f4 bc31a6c4d142fa3fbdcae69d5ba6f1cec00eb9ad92b46c8d7b91ebfa7ef6c1f4
lib/codeql/swift/generated/Raw.qll 118b43fedd4265b5aa15c33ef01a2f5a5db6e5597f95bef1078a01c3ff8da983 075aec2c8b232f0361ebf63f07ae9b66163f3975e6023583fb0fa2e40b979a33
lib/codeql/swift/generated/Raw.qll 2c5cecbc73f87d81a7e6dd6e125115619c1b034712f1906fed084e997bb3fe05 9653595693da55953d7743fbecce33d16910e3b6737c654311f1e34d27ad7f0b
lib/codeql/swift/generated/Synth.qll 31e318c6e156848c85a2a2664695b48b5e93c57c9bb22fa29d027069907b3ab0 8655ffcf772f55284b93f1d7f8e1b3d497a9744d5f2e0c17bc322c1fdf8bdba8
lib/codeql/swift/generated/SynthConstructors.qll 3e53c7853096020219c01dae85681fe80b34938d198a0ff359a209dda41c5ed7 3e53c7853096020219c01dae85681fe80b34938d198a0ff359a209dda41c5ed7
lib/codeql/swift/generated/UnknownFile.qll 247ddf2ebb49ce5ed4bf7bf91a969ddff37de6c78d43d8affccaf7eb586e06f2 452b29f0465ef45e978ef8b647b75e5a2a1e53f2a568fc003bc8f52f73b3fa4d
@@ -915,7 +915,7 @@ lib/codeql/swift/generated/stmt/DoCatchStmt.qll 93c2a47088a2849ccf1a5647eba39c1a
lib/codeql/swift/generated/stmt/DoStmt.qll 27be70a901a20831fea3d3dcf45d5ba9048043b1894cb04c09dfb3d1c0241cef 48a258a27677170e1d5530eb0001b6c043d96a92e0d056e6fb428b4d7ac4cadd
lib/codeql/swift/generated/stmt/FailStmt.qll 72bfd7dc0f3f8219f3cce1a34567fdd127823e2cf42274e171f7ac96eb18afcd cb1027b33e5b601317546acb8915a5985e04b5376ecaea012b3ecdffc22ae814
lib/codeql/swift/generated/stmt/FallthroughStmt.qll 7aa70d87443d03b0ba7ed7c7b57b501abb00a32c5943c99c40735d023cf7a9ef 6451f355980409d0d7d991b9e241324ee2b68be3838440f206f734470c7188fc
lib/codeql/swift/generated/stmt/ForEachStmt.qll b5cadd1b5daa3601d094e79143cf85a731966a3c1e1c6567bcd0d87f33f9196f 13a494dd3cbbc34c8d1caeda7f279c35d971b8fb49823c89cf71675f7d76e6a4
lib/codeql/swift/generated/stmt/ForEachStmt.qll d2e4bd83e68a432515284273d682ee47dc61860ff1b0769b9c3775ceb8d46140 848ed0efec1a40df27259492c4df1603d6bfcd8622038beac8d9145fc6863de6
lib/codeql/swift/generated/stmt/GuardStmt.qll a957b2d83c92ac7ed18f76faa35cb71b10ce0dcbb88447b57dcdc034341b6fcc 518fad136831573112edf3836e852c82009a654ce256077d953ddc6b86231efb
lib/codeql/swift/generated/stmt/IfStmt.qll a1d1af8679fb0881bace45c251f96f3bbb07e8a0312dd5ecab4fc2c07e491682 bad75ae703b23d1b8869be108f095ec242996cdde0dd90b8c1dabe643869da60
lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll c05bbbdba0ad8e33afdae3a8b201276d95c2b4d1e43b9b58aa4aa17765dc7ca4 c30a5a1350172459bf67760dc912460ecc4f581dd927a98a068d95cb0905f0d9
@@ -1232,7 +1232,12 @@ test/extractor-tests/generated/stmt/DoCatchStmt/MISSING_SOURCE.txt 35fb32ea53931
test/extractor-tests/generated/stmt/DoStmt/MISSING_SOURCE.txt 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d
test/extractor-tests/generated/stmt/FailStmt/FailStmt.ql db2d21fe1b01949180ff11416f2dc0a6a561f9ac9e6a5654156f947c584971de 2cf787b54819077dd2b4da870b722396ebf953e05bf0b1c393affef2b1fe11ba
test/extractor-tests/generated/stmt/FallthroughStmt/MISSING_SOURCE.txt 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d
test/extractor-tests/generated/stmt/ForEachStmt/MISSING_SOURCE.txt 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d
test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt.ql 093a6619940636974e2a59f085937f9fa8645a134199c130ee99babfd2c1f1a0 068daffb2da1be9135eb818190926af3958d503c3c61de2659c0c0e167b2d11c
test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getIteratorVar.ql 1b8689dda5defd45c8bb743b30d723ed7b0c80ca54b81fb0f5fcf76620ec4ef4 1e48e40cff37194e0ea2b69997177237145fa1070e84c8f701a03d71416652b5
test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getLabel.ql 1cf0663cd16886d4361bedad93759ab84fcaf54d5fbf16d7d2f4108f74c38683 129778f5f36d10e8a10452f333304fef9b95919cfe367ce6ff7309e2d3f3ab3b
test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getNextCall.ql 503106f20025ec479ffe46daf13ff80f5d824b657c43da8185ae2d74af8740a3 551e33f70028268e3b3790c17907101be768c42811b62978ed10ffc0a65e25d0
test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getVariable.ql 749149b5164f493bb49726e1d54cdd1c85607566c0ba7adfc3514ea953b1f40e 1695a631aeeb47e6a0d22ec18d713f1fe2f730684269fc6e50c70020a78fbf3c
test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getWhere.ql 536af56264054a7af626a5ca4bb5bcc5b8f13299d11c499a110e4f12e2c166b6 bfd8b355342b0a03ced022b31d39e9adc6d7820a28394315392a9e2fc7647555
test/extractor-tests/generated/stmt/GuardStmt/MISSING_SOURCE.txt 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d
test/extractor-tests/generated/stmt/IfStmt/MISSING_SOURCE.txt 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d 35fb32ea5393152eb7a875b20b4e3e4b8c7a997a8959c32417140d57a16a052d
test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.ql 46b702865ef1dc4d9d8332a3d68ba295a1f8ce9737dbcb07a5ef4c701c021789 07eaec1abc763a4f2339466fd0f06d12c4ca21d9eeb21ab1f7366916dafc4854

7
swift/ql/.gitattributes generated vendored
View File

@@ -1234,7 +1234,12 @@
/test/extractor-tests/generated/stmt/DoStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/FailStmt/FailStmt.ql linguist-generated
/test/extractor-tests/generated/stmt/FallthroughStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/ForEachStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt.ql linguist-generated
/test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getIteratorVar.ql linguist-generated
/test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getLabel.ql linguist-generated
/test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getNextCall.ql linguist-generated
/test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getVariable.ql linguist-generated
/test/extractor-tests/generated/stmt/ForEachStmt/ForEachStmt_getWhere.ql linguist-generated
/test/extractor-tests/generated/stmt/GuardStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/IfStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.ql linguist-generated

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,

View File

@@ -0,0 +1,3 @@
| for.swift:4:5:6:5 | for ... in ... where ... { ... } | hasLabel: | no | getNumberOfVariables: | 2 | getPattern: | for.swift:4:9:4:9 | x | hasWhere: | yes | hasIteratorVar: | yes | hasNextCall: | yes | getBody: | for.swift:4:32:6:5 | { ... } |
| for.swift:7:5:9:5 | for ... in ... { ... } | hasLabel: | no | getNumberOfVariables: | 2 | getPattern: | for.swift:7:9:7:9 | s | hasWhere: | no | hasIteratorVar: | yes | hasNextCall: | yes | getBody: | for.swift:7:23:9:5 | { ... } |
| for.swift:13:5:17:5 | for ... in ... { ... } | hasLabel: | no | getNumberOfVariables: | 1 | getPattern: | for.swift:13:9:13:9 | x | hasWhere: | no | hasIteratorVar: | no | hasNextCall: | no | getBody: | for.swift:13:32:17:5 | { ... } |

View File

@@ -0,0 +1,20 @@
// generated by codegen/codegen.py, do not edit
import codeql.swift.elements
import TestUtils
from
ForEachStmt x, string hasLabel, int getNumberOfVariables, Pattern getPattern, string hasWhere,
string hasIteratorVar, string hasNextCall, BraceStmt getBody
where
toBeTested(x) and
not x.isUnknown() and
(if x.hasLabel() then hasLabel = "yes" else hasLabel = "no") and
getNumberOfVariables = x.getNumberOfVariables() and
getPattern = x.getPattern() and
(if x.hasWhere() then hasWhere = "yes" else hasWhere = "no") and
(if x.hasIteratorVar() then hasIteratorVar = "yes" else hasIteratorVar = "no") and
(if x.hasNextCall() then hasNextCall = "yes" else hasNextCall = "no") and
getBody = x.getBody()
select x, "hasLabel:", hasLabel, "getNumberOfVariables:", getNumberOfVariables, "getPattern:",
getPattern, "hasWhere:", hasWhere, "hasIteratorVar:", hasIteratorVar, "hasNextCall:", hasNextCall,
"getBody:", getBody

View File

@@ -0,0 +1,2 @@
| for.swift:4:5:6:5 | for ... in ... where ... { ... } | file://:0:0:0:0 | var ... = ... |
| for.swift:7:5:9:5 | for ... in ... { ... } | file://:0:0:0:0 | var ... = ... |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py, do not edit
import codeql.swift.elements
import TestUtils
from ForEachStmt x
where toBeTested(x) and not x.isUnknown()
select x, x.getIteratorVar()

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py, do not edit
import codeql.swift.elements
import TestUtils
from ForEachStmt x
where toBeTested(x) and not x.isUnknown()
select x, x.getLabel()

View File

@@ -0,0 +1,2 @@
| for.swift:4:5:6:5 | for ... in ... where ... { ... } | for.swift:4:5:4:5 | call to next() |
| for.swift:7:5:9:5 | for ... in ... { ... } | for.swift:7:5:7:5 | call to next() |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py, do not edit
import codeql.swift.elements
import TestUtils
from ForEachStmt x
where toBeTested(x) and not x.isUnknown()
select x, x.getNextCall()

View File

@@ -0,0 +1,5 @@
| for.swift:4:5:6:5 | for ... in ... where ... { ... } | 0 | for.swift:4:9:4:9 | x |
| for.swift:4:5:6:5 | for ... in ... where ... { ... } | 1 | for.swift:4:14:4:14 | $x$generator |
| for.swift:7:5:9:5 | for ... in ... { ... } | 0 | for.swift:7:9:7:9 | s |
| for.swift:7:5:9:5 | for ... in ... { ... } | 1 | for.swift:7:14:7:14 | $s$generator |
| for.swift:13:5:17:5 | for ... in ... { ... } | 0 | for.swift:13:9:13:9 | x |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py, do not edit
import codeql.swift.elements
import TestUtils
from ForEachStmt x, int index
where toBeTested(x) and not x.isUnknown()
select x, index, x.getVariable(index)

View File

@@ -0,0 +1 @@
| for.swift:4:5:6:5 | for ... in ... where ... { ... } | for.swift:4:25:4:30 | ... .!=(_:_:) ... |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py, do not edit
import codeql.swift.elements
import TestUtils
from ForEachStmt x
where toBeTested(x) and not x.isUnknown()
select x, x.getWhere()

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py, do not edit
After a source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -0,0 +1,19 @@
struct S {}
func test_sequence(_ ints: [Int], _ elements: [S]) {
for x in ints where x != 0 {
print(x)
}
for s in elements {
print(s)
}
}
func test_variadic_pack<each T>(_ array: repeat [each T]) -> Bool {
for x in repeat each array {
if !x.isEmpty {
return false
}
}
return true
}

View File

@@ -187,6 +187,7 @@ methodlookup.swift:
# 40| getBase(): [TypeExpr] Bar.Type
# 40| getTypeRepr(): [TypeRepr] Bar
# 40| getMethodRef(): [DeclRefExpr] staticMethod()
# 33| getExpr().getFullyConverted(): [FunctionConversionExpr] (@isolated(any) () async -> ()) ...
# 33| [NilLiteralExpr] nil
# 38| [Comment] // Bar.instanceMethod(bar2)() // error: actor-isolated instance method 'instanceMethod()' can not be referenced from a non-isolated context
# 38|
@@ -262,6 +263,7 @@ methodlookup.swift:
# 51| getMethodRef(): [DeclRefExpr] staticMethod()
# 51| getMethodRef().getFullyConverted(): [FunctionConversionExpr] ((Baz.Type) -> @MainActor () -> ()) ...
# 51| getElement(5).getFullyConverted(): [AwaitExpr] await ...
# 43| getExpr().getFullyConverted(): [FunctionConversionExpr] (@isolated(any) () async -> ()) ...
# 43| [NilLiteralExpr] nil
# 47| [Comment] // DotSyntaxCallExpr
# 47|

View File

@@ -1016,6 +1016,7 @@ class DoStmt(LabeledStmt):
body: BraceStmt | child
class ForEachStmt(LabeledStmt):
variables: list[VarDecl] | child
pattern: Pattern | child
where: optional[Expr] | child
iteratorVar: optional[PatternBindingDecl] | child