Swift: clean up VarDecl, NamedPattern and SwitchStmt interactions

* `variables` under `CaseStmt` are now AST children, which solves
  orphan `VarDecl`s in that case
* reordered `CaseStmt` AST children to be `labels > variables > body`
  (was `body > labels`)
* made `NamedPattern::getVarDecl` an extracted property instead of
  `getName`
* The above led to duplicate DB entities because of a quirk in the
  Swift compiler code. This is solved by tweaking the extraction of
  `variables` under `CaseStmt` to not use `getCaseBodyVariables`.
This commit is contained in:
Paolo Tranquilli
2023-10-23 12:37:32 +02:00
parent 140ff723e4
commit f22d60f011
36 changed files with 602 additions and 327 deletions

View File

@@ -4,7 +4,7 @@ namespace codeql {
codeql::NamedPattern PatternTranslator::translateNamedPattern(const swift::NamedPattern& pattern) {
auto entry = dispatcher.createEntry(pattern);
entry.name = pattern.getNameStr().str();
entry.var_decl = dispatcher.fetchLabel(pattern.getDecl());
return entry;
}

View File

@@ -73,7 +73,7 @@ codeql::ForEachStmt StmtTranslator::translateForEachStmt(const swift::ForEachStm
auto entry = dispatcher.createEntry(stmt);
fillLabeledStmt(stmt, entry);
entry.body = dispatcher.fetchLabel(stmt.getBody());
// entry.sequence = dispatcher.fetchLabel(stmt.getTypeCheckedSequence());
// entry.sequence = dispatcher.fetchLabel(stmt.getTypeCheckedSequence());
entry.pattern = dispatcher.fetchLabel(stmt.getPattern());
entry.iteratorVar = dispatcher.fetchLabel(stmt.getIteratorVar());
entry.where = dispatcher.fetchOptionalLabel(stmt.getWhere());
@@ -133,12 +133,17 @@ codeql::DoCatchStmt StmtTranslator::translateDoCatchStmt(const swift::DoCatchStm
codeql::CaseStmt StmtTranslator::translateCaseStmt(const swift::CaseStmt& stmt) {
auto entry = dispatcher.createEntry(stmt);
auto labels = stmt.getCaseLabelItems();
entry.body = dispatcher.fetchLabel(stmt.getBody());
entry.labels = dispatcher.fetchRepeatedLabels(stmt.getCaseLabelItems());
if (stmt.hasCaseBodyVariables()) {
for (auto var : stmt.getCaseBodyVariables()) {
entry.variables.push_back(dispatcher.fetchLabel(var));
}
entry.labels = dispatcher.fetchRepeatedLabels(labels);
// we don't use stmt.getCaseBodyVariables() because it's actually filled with copies of the
// variable declarations, which would lead to duplicate `DeclVar` entities.
// Instead we follow the same logic that's used to fill getCaseBodyVariables, looking at the first
// pattern and collecting variables from it. See
// https://github.com/apple/swift/blob/71fff6649b3ce57cc22954f141cf8b567be6de88/lib/Parse/ParseStmt.cpp#L2210
if (!labels.empty() && labels.front().getPattern()) {
labels.front().getPattern()->forEachVariable(
[&](const swift::VarDecl* var) { entry.variables.push_back(dispatcher.fetchLabel(var)); });
}
return entry;
}

View File

@@ -376,10 +376,10 @@ lib/codeql/swift/generated/KeyPathComponent.qll c79c7bc04fc1426992ab472eedc1a20a
lib/codeql/swift/generated/Locatable.qll be20967d48a34cdba126fe298606e0adc11697831f097acba9c52a0b7ce9983e 8aa01bc376614abbc3209e25785c72f86c9b4e94bb5f471a4a0677fedaec4f61
lib/codeql/swift/generated/Location.qll c5793987e77812059a28254dadee29bfe9b38153c0399fbb1bf6a2f5c237fdab 6e6d8802b021e36bbaad81845657769dd48a798ea33080ada05e9818a20b38f7
lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5
lib/codeql/swift/generated/ParentChild.qll 6e7b64896a2ad25a06130592ba27036e0e2b9bf4268a730d1bce78ebaf32607d dfe0e3c578f726cf2b7d024bf247701f12d6a79fd061a3c805d23fac85218635
lib/codeql/swift/generated/ParentChild.qll f2c1bcd5495f9b72cf43f7fe9691e888071e128069c1a4cb43feecec55fd0ab6 95c801caf726159580192fb6f93e2218776014fb0def04ec423dff3f245d53c1
lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0
lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98
lib/codeql/swift/generated/Raw.qll 349eb78e973669d9f30922399571bc31313f781c82c2993cdae4b03493440c1d 1537b15a42b35dd7e22a7e22e70dce38ed93e00e79678bbd78cfd14c1433fcbe
lib/codeql/swift/generated/Raw.qll 72b362fb6c19eb88de89780bfeda5cb2c4ab5f68e24fd5c0fe6220acd49d48b7 2442908ec02efcf633f9bf137b52e024bd6b9001961b27e932d21007accbb1ee
lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814
lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4
lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6
@@ -556,7 +556,7 @@ lib/codeql/swift/generated/pattern/BoolPattern.qll 118300aa665defa688a7c28f82deb
lib/codeql/swift/generated/pattern/EnumElementPattern.qll 2d92a861316d46190e11880b0c383651e4ea15ea8fb81f55c08c4ce733bee2c7 c5915d7a3b62f7c009daac2e7d87c7d435a81a128bdfcc1db9ad281600acfb67
lib/codeql/swift/generated/pattern/ExprPattern.qll 169cef487e499a21d0d2cc4eda7268eb29cb6b1081fa6a0bc4e8571677f063f3 b7f3160f0812cf565873b607a247e184f17cc0289758f9a46748e90e783abd4f
lib/codeql/swift/generated/pattern/IsPattern.qll c809159dff26b86d44f560742d66e75b3cf143cdfc0f3933b959864412770248 7375cb8140da3c1531b55b084c4b6aa8009495dd40697a13f05b258d3f5677cc
lib/codeql/swift/generated/pattern/NamedPattern.qll 5d25e51eb83e86363b95a6531ffb164e5a6070b4a577f3900140edbef0e83c71 9e88b2b2b90a547b402d4782e8d494bc555d4200763c094dd985fe3b7ebc1ec8
lib/codeql/swift/generated/pattern/NamedPattern.qll de29f055d43087ada4ffbad33bdf50887a140820a308d3b8ff7f00f0a05134ee 8a9ff5b0b6fc78ab726058f6e4b6e7eef80dd780d76b1b3d5a2bec7dfa320306
lib/codeql/swift/generated/pattern/OptionalSomePattern.qll 5b9c7032584619d4921d1a1324e3ce4bd7207f0d4daa703e1e059f983bf1b132 e6d44514cd123a7ad27f657a2b83d46277a961a849139380ece886430a862920
lib/codeql/swift/generated/pattern/ParenPattern.qll 337cb03dcb7384f7ef13e35d843b3498c0ae391374f5e870d1e52c2d1baacd95 cba288ee99726f5bbf15cf61971e000a835cf6e8b7507dcf6f6c6dea91ec287a
lib/codeql/swift/generated/pattern/Pattern.qll 0e96528a8dd87185f4fb23ba33ea418932762127e99739d7e56e5c8988e024d1 ba1e010c9f7f891048fb8c4ff8ea5a6c664c09e43d74b860d559f6459f82554a
@@ -565,7 +565,7 @@ lib/codeql/swift/generated/pattern/TypedPattern.qll 6a9fd2815755eddc6918d6be8221
lib/codeql/swift/generated/stmt/BraceStmt.qll 5273745afaaf10dc4b6ee159ca304e1251dc11af3c86af812b28294cbbcf2597 dbd4b003b453742e7197b22633ec8c87418e207f7ca409a04e3c6fb2cf2ea5fd
lib/codeql/swift/generated/stmt/BreakStmt.qll 879cf66911cc7f53e7e8f4ae8244681018fb17d6501b269fb7cf9d8481f0b539 c78fc1b0e3e76321fc1653aa8b0aabaaacf082e01a003b78f693b106cc05faa0
lib/codeql/swift/generated/stmt/CaseLabelItem.qll 9536d2909a274c3a969eec25f8e5966adfaa9b0d6451ea6319d9f7bb2fd6fe07 02e25f036db50e9a6e9a7ceab6002dd605b73afb55fa1dee6f22e7af33a40913
lib/codeql/swift/generated/stmt/CaseStmt.qll c180478c6161439bc76bd39edfab343faba7450900ffedcadd3ccea12dc3a08c b537eb517db76113cfbc91c59e6bdfbf16ff83d639dfe6fd6892171f71a97090
lib/codeql/swift/generated/stmt/CaseStmt.qll fb92601b5e93ac4b0e99a910baf2586725ef83075d0363c64a4fe1d036effefa c56801706bea64ec76ec942f193c43d330c10612da9414d2d343af74960e1982
lib/codeql/swift/generated/stmt/ConditionElement.qll 29c1f9ab045cceac466836c8c6b9b158395351a76d4c4f8725d98663ea75b9de 09342a6d9632a1af973ef21fd03d30ca85b94ebb7d51991b4b573ce9096f97f4
lib/codeql/swift/generated/stmt/ContinueStmt.qll bf300c9655f750db8e71eb530d8972eca1ac9bf022023c8d99e299de8f5b3a44 746a2432752743e18e2b5fa4b46407e5d4c0e6ee38635c6de0846452cbc5eec5
lib/codeql/swift/generated/stmt/DeferStmt.qll 230f8c8f53c86afd3169b36214c03c54ac3e5240b1c1c1ade4446b45c4c3c32a d0d9e728be7506aa07904c53087eb1273a82762139866767abb0b851f3e559ee
@@ -854,8 +854,6 @@ test/extractor-tests/generated/pattern/TuplePattern/MISSING_SOURCE.txt 66846d526
test/extractor-tests/generated/pattern/TypedPattern/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/BraceStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/BreakStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/CaseLabelItem/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/CaseStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/ConditionElement/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/ContinueStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/DeferStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
@@ -870,7 +868,14 @@ test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.ql dc72e3a7f
test/extractor-tests/generated/stmt/RepeatWhileStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/ReturnStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/StmtCondition/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/SwitchStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/SwitchStmt/CaseLabelItem.ql 6a95c434a2cc23714e888582db5c72b423ed4fe4f41f39e6382fa72cb54e1b25 1cdbb9652d78f2d46f9238dc47982dd3b3c2e8183f1c560686af0bdf232ff161
test/extractor-tests/generated/stmt/SwitchStmt/CaseLabelItem_getGuard.ql f561d4d0583c7c978da66a2f45a5a3cdcb6c21d431d69435bb2d223449b68e2c 3663f0cab05b5993c6e22a24756157297a3704acf68670a73547ed66f9d29a49
test/extractor-tests/generated/stmt/SwitchStmt/CaseStmt.ql 1660daf75c6a1a20bd2dbb334c05395b76e01ac2d21e400df62d64ae77032d04 74bbb0c7abe299484cfcc0e433f1ef09d7c608859e44f18c0bebec64761423d6
test/extractor-tests/generated/stmt/SwitchStmt/CaseStmt_getLabel.ql d1e93510f4fd55937236714c8fb374daf90b281390a8cd23807f096229e4f8c8 90070b50cf06abcd26286ef40a23e8fc2ff6b82d413fb010a5dc20eaa0a8d116
test/extractor-tests/generated/stmt/SwitchStmt/CaseStmt_getVariable.ql 3afec99b34d0c29051c0043a2a24b03e5b0edca65b3657a639d2888b518ff3e0 36a2d7a8202a595e6f8c21b70b48042fd7cc5d271139fb24dd999d7e07c61f5d
test/extractor-tests/generated/stmt/SwitchStmt/SwitchStmt.ql 6b16bc2b345520905ba1923e5a554d6599e7f16916fe4e50f128970f89d3e8df 95d60c9e914068cce977ae27048d190ad2ed68eb3c9e7357ab3dfc64a0503612
test/extractor-tests/generated/stmt/SwitchStmt/SwitchStmt_getCase.ql 6958d28a8256e213108cb356af9467143f2ffcd31c45b08c177fc858194f8f3d cf9dacdcd68269d7218bc8ca9cb0ffe9c3cdcf968833393f00e65ca486a5b5b1
test/extractor-tests/generated/stmt/SwitchStmt/SwitchStmt_getLabel.ql b96b047146c4f1dd09f819ca5943f13ee0dc5277398eedd89b96dcd177d8d9cf a94cf29c6b7e19dac10443fb29063b4f0ac81b8853ea7c39f3b43265d2180eab
test/extractor-tests/generated/stmt/ThrowStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/WhileStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/stmt/YieldStmt/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7

11
swift/ql/.gitattributes generated vendored
View File

@@ -856,8 +856,6 @@
/test/extractor-tests/generated/pattern/TypedPattern/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/BraceStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/BreakStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/CaseLabelItem/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/CaseStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/ConditionElement/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/ContinueStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/DeferStmt/MISSING_SOURCE.txt linguist-generated
@@ -872,7 +870,14 @@
/test/extractor-tests/generated/stmt/RepeatWhileStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/ReturnStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/StmtCondition/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/CaseLabelItem.ql linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/CaseLabelItem_getGuard.ql linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/CaseStmt.ql linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/CaseStmt_getLabel.ql linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/CaseStmt_getVariable.ql linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/SwitchStmt.ql linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/SwitchStmt_getCase.ql linguist-generated
/test/extractor-tests/generated/stmt/SwitchStmt/SwitchStmt_getLabel.ql linguist-generated
/test/extractor-tests/generated/stmt/ThrowStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/WhileStmt/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/stmt/YieldStmt/MISSING_SOURCE.txt linguist-generated

View File

@@ -9,19 +9,16 @@ private import codeql.swift.elements.decl.VarDecl
*/
class NamedPattern extends Generated::NamedPattern {
/**
* Holds if this named pattern has a corresponding `VarDecl`.
* This will be the case as long as the variable is subsequently used.
* Holds if this named pattern has a corresponding `VarDecl`, which is currently always true.
*
* DEPRECATED: unless there was a compilation error, this will always hold.
*/
predicate hasVarDecl() { exists(this.getVarDecl()) }
deprecated predicate hasVarDecl() { exists(this.getVarDecl()) }
/**
* Gets the `VarDecl` bound by this named pattern, if any.
* This will be the case as long as the variable is subsequently used.
* Gets the name of the variable bound by this pattern.
*/
VarDecl getVarDecl() {
this.getImmediateEnclosingPattern*() = result.getImmediateParentPattern() and
pragma[only_bind_out](result.getName()) = pragma[only_bind_out](this.getName())
}
string getName() { result = this.getVarDecl().getName() }
override string toString() { result = this.getName() }
}

View File

@@ -3472,21 +3472,25 @@ private module Impl {
}
private Element getImmediateChildOfCaseStmt(CaseStmt e, int index, string partialPredicateCall) {
exists(int b, int bStmt, int n, int nBody, int nLabel |
exists(int b, int bStmt, int n, int nLabel, int nVariable, int nBody |
b = 0 and
bStmt = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfStmt(e, i, _)) | i) and
n = bStmt and
nBody = n + 1 and
nLabel = nBody + 1 + max(int i | i = -1 or exists(e.getLabel(i)) | i) and
nLabel = n + 1 + max(int i | i = -1 or exists(e.getLabel(i)) | i) and
nVariable = nLabel + 1 + max(int i | i = -1 or exists(e.getVariable(i)) | i) and
nBody = nVariable + 1 and
(
none()
or
result = getImmediateChildOfStmt(e, index - b, partialPredicateCall)
or
index = n and result = e.getBody() and partialPredicateCall = "Body()"
result = e.getLabel(index - n) and
partialPredicateCall = "Label(" + (index - n).toString() + ")"
or
result = e.getLabel(index - nBody) and
partialPredicateCall = "Label(" + (index - nBody).toString() + ")"
result = e.getVariable(index - nLabel) and
partialPredicateCall = "Variable(" + (index - nLabel).toString() + ")"
or
index = nVariable and result = e.getBody() and partialPredicateCall = "Body()"
)
)
}

View File

@@ -2454,9 +2454,9 @@ module Raw {
override string toString() { result = "NamedPattern" }
/**
* Gets the name of this named pattern.
* Gets the variable declaration of this named pattern.
*/
string getName() { named_patterns(this, result) }
VarDecl getVarDecl() { named_patterns(this, result) }
}
/**
@@ -2608,11 +2608,6 @@ module Raw {
class CaseStmt extends @case_stmt, Stmt {
override string toString() { result = "CaseStmt" }
/**
* Gets the body of this case statement.
*/
Stmt getBody() { case_stmts(this, result) }
/**
* Gets the `index`th label of this case statement (0-based).
*/
@@ -2622,6 +2617,11 @@ module Raw {
* Gets the `index`th variable of this case statement (0-based).
*/
VarDecl getVariable(int index) { case_stmt_variables(this, index, result) }
/**
* Gets the body of this case statement.
*/
Stmt getBody() { case_stmts(this, result) }
}
/**

View File

@@ -2,16 +2,20 @@
private import codeql.swift.generated.Synth
private import codeql.swift.generated.Raw
import codeql.swift.elements.pattern.Pattern
import codeql.swift.elements.decl.VarDecl
module Generated {
class NamedPattern extends Synth::TNamedPattern, Pattern {
override string getAPrimaryQlClass() { result = "NamedPattern" }
/**
* Gets the name of this named pattern.
* Gets the variable declaration of this named pattern.
*/
string getName() {
result = Synth::convertNamedPatternToRaw(this).(Raw::NamedPattern).getName()
VarDecl getVarDecl() {
result =
Synth::convertVarDeclFromRaw(Synth::convertNamedPatternToRaw(this)
.(Raw::NamedPattern)
.getVarDecl())
}
}
}

View File

@@ -9,14 +9,6 @@ module Generated {
class CaseStmt extends Synth::TCaseStmt, Stmt {
override string getAPrimaryQlClass() { result = "CaseStmt" }
/**
* Gets the body of this case statement.
*/
Stmt getBody() {
result =
Synth::convertStmtFromRaw(Synth::convertCaseStmtToRaw(this).(Raw::CaseStmt).getBody())
}
/**
* Gets the `index`th label of this case statement (0-based).
*/
@@ -56,5 +48,13 @@ module Generated {
* Gets the number of variables of this case statement.
*/
final int getNumberOfVariables() { result = count(int i | exists(this.getVariable(i))) }
/**
* Gets the body of this case statement.
*/
Stmt getBody() {
result =
Synth::convertStmtFromRaw(Synth::convertCaseStmtToRaw(this).(Raw::CaseStmt).getBody())
}
}
}

View File

@@ -1671,7 +1671,7 @@ is_pattern_sub_patterns( //dir=pattern
named_patterns( //dir=pattern
unique int id: @named_pattern,
string name: string ref
int var_decl: @var_decl_or_none ref
);
optional_some_patterns( //dir=pattern

View File

@@ -1,3 +1,4 @@
| var_decls.swift:2:7:2:7 | i | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 0 | getName: | i | getType: | Int | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | no | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 0 |
| var_decls.swift:2:12:2:12 | $i$generator | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | IndexingIterator<ClosedRange<Int>> | getNumberOfAccessors: | 0 | getName: | $i$generator | getType: | IndexingIterator<ClosedRange<Int>> | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | yes | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 1 |
| var_decls.swift:4:7:4:7 | i | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 0 | getName: | i | getType: | Int | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | yes | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 1 |
| var_decls.swift:7:5:7:5 | numbers | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | [Int] | getNumberOfAccessors: | 0 | getName: | numbers | getType: | [Int] | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | yes | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 1 |
@@ -21,3 +22,8 @@
| var_decls.swift:57:36:57:36 | $w4 | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Bool | getNumberOfAccessors: | 2 | getName: | $w4 | getType: | Bool | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | no | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 1 |
| var_decls.swift:57:36:57:36 | _w4 | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | WrapperWithProjectedAndInit | getNumberOfAccessors: | 0 | getName: | _w4 | getType: | WrapperWithProjectedAndInit | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | yes | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 1 |
| var_decls.swift:57:36:57:36 | w4 | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 2 | getName: | w4 | getType: | Int | hasAttachedPropertyWrapperType: | yes | hasParentPattern: | yes | hasParentInitializer: | yes | hasPropertyWrapperBackingVarBinding: | yes | hasPropertyWrapperBackingVar: | yes | hasPropertyWrapperProjectionVarBinding: | yes | hasPropertyWrapperProjectionVar: | yes | getIntroducerInt: | 1 |
| var_decls.swift:65:19:65:19 | case_variable | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 0 | getName: | case_variable | getType: | Int | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | no | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 0 |
| var_decls.swift:65:19:65:19 | case_variable | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 0 | getName: | case_variable | getType: | Int | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | no | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 0 |
| var_decls.swift:65:34:65:34 | $match | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 0 | getName: | $match | getType: | Int | hasAttachedPropertyWrapperType: | no | hasParentPattern: | no | hasParentInitializer: | no | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 0 |
| var_decls.swift:67:15:67:15 | $match | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 0 | getName: | $match | getType: | Int | hasAttachedPropertyWrapperType: | no | hasParentPattern: | no | hasParentInitializer: | no | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 0 |
| var_decls.swift:67:22:67:22 | unused_case_variable | getModule: | file://:0:0:0:0 | var_decls | getNumberOfMembers: | 0 | getInterfaceType: | Int | getNumberOfAccessors: | 0 | getName: | unused_case_variable | getType: | Int | hasAttachedPropertyWrapperType: | no | hasParentPattern: | yes | hasParentInitializer: | no | hasPropertyWrapperBackingVarBinding: | no | hasPropertyWrapperBackingVar: | no | hasPropertyWrapperProjectionVarBinding: | no | hasPropertyWrapperProjectionVar: | no | getIntroducerInt: | 0 |

View File

@@ -1,3 +1,4 @@
| var_decls.swift:2:7:2:7 | i | var_decls.swift:2:7:2:7 | i |
| var_decls.swift:2:12:2:12 | $i$generator | var_decls.swift:2:12:2:12 | $i$generator |
| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:7:4:7 | i |
| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:5:7:5 | numbers |
@@ -21,3 +22,6 @@
| var_decls.swift:57:36:57:36 | $w4 | var_decls.swift:57:36:57:36 | ... as ... |
| var_decls.swift:57:36:57:36 | _w4 | var_decls.swift:57:36:57:36 | ... as ... |
| var_decls.swift:57:36:57:36 | w4 | var_decls.swift:57:36:57:36 | w4 |
| var_decls.swift:65:19:65:19 | case_variable | var_decls.swift:65:8:65:35 | .value(...) |
| var_decls.swift:65:19:65:19 | case_variable | var_decls.swift:65:8:65:35 | .value(...) |
| var_decls.swift:67:22:67:22 | unused_case_variable | var_decls.swift:67:8:67:42 | .value(...) |

View File

@@ -56,3 +56,16 @@ func f3() {
@WrapperWithProjected var w3 = 3
@WrapperWithProjectedAndInit var w4 = 4
}
enum E {
case value(Int, Int)
}
switch E.value(42, 0) {
case .value(let case_variable, 0):
_ = case_variable
case .value(0, let unused_case_variable):
break
default:
break
}

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
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

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
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,13 @@
| switch.swift:3:9:3:9 | =~ ... | getPattern: | switch.swift:3:9:3:9 | =~ ... | hasGuard: | no |
| switch.swift:6:9:6:9 | =~ ... | getPattern: | switch.swift:6:9:6:9 | =~ ... | hasGuard: | no |
| switch.swift:6:12:6:12 | =~ ... | getPattern: | switch.swift:6:12:6:12 | =~ ... | hasGuard: | no |
| switch.swift:8:9:8:26 | x where ... | getPattern: | switch.swift:8:13:8:13 | x | hasGuard: | yes |
| switch.swift:10:4:10:4 | _ | getPattern: | switch.swift:10:4:10:4 | _ | hasGuard: | no |
| switch.swift:22:8:22:9 | .one | getPattern: | switch.swift:22:8:22:9 | .one | hasGuard: | no |
| switch.swift:24:8:24:40 | .two(...) where ... | getPattern: | switch.swift:24:8:24:25 | .two(...) | hasGuard: | yes |
| switch.swift:26:8:26:25 | .two(...) | getPattern: | switch.swift:26:8:26:25 | .two(...) | hasGuard: | no |
| switch.swift:28:8:28:23 | .three(...) | getPattern: | switch.swift:28:8:28:23 | .three(...) | hasGuard: | no |
| switch.swift:33:8:33:21 | .two(...) | getPattern: | switch.swift:33:8:33:21 | .two(...) | hasGuard: | no |
| switch.swift:35:13:35:13 | =~ ... | getPattern: | switch.swift:35:13:35:13 | =~ ... | hasGuard: | no |
| switch.swift:37:8:37:8 | _ | getPattern: | switch.swift:37:8:37:8 | _ | hasGuard: | no |
| switch.swift:40:3:40:3 | _ | getPattern: | switch.swift:40:3:40:3 | _ | hasGuard: | no |

View File

@@ -0,0 +1,11 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from CaseLabelItem x, Pattern getPattern, string hasGuard
where
toBeTested(x) and
not x.isUnknown() and
getPattern = x.getPattern() and
if x.hasGuard() then hasGuard = "yes" else hasGuard = "no"
select x, "getPattern:", getPattern, "hasGuard:", hasGuard

View File

@@ -0,0 +1,2 @@
| switch.swift:8:9:8:26 | x where ... | switch.swift:8:21:8:26 | ... .>=(_:_:) ... |
| switch.swift:24:8:24:40 | .two(...) where ... | switch.swift:24:33:24:40 | ... .==(_:_:) ... |

View File

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

View File

@@ -0,0 +1,12 @@
| switch.swift:3:4:5:7 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 0 | getBody: | switch.swift:4:7:5:7 | { ... } |
| switch.swift:6:4:7:20 | case ... | getNumberOfLabels: | 2 | getNumberOfVariables: | 0 | getBody: | switch.swift:7:7:7:20 | { ... } |
| switch.swift:8:4:9:18 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 1 | getBody: | switch.swift:9:7:9:18 | { ... } |
| switch.swift:10:4:11:22 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 0 | getBody: | switch.swift:11:7:11:22 | { ... } |
| switch.swift:22:3:23:5 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 0 | getBody: | switch.swift:23:5:23:5 | { ... } |
| switch.swift:24:3:25:5 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 2 | getBody: | switch.swift:25:5:25:5 | { ... } |
| switch.swift:26:3:27:5 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 2 | getBody: | switch.swift:27:5:27:5 | { ... } |
| switch.swift:28:3:29:5 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 1 | getBody: | switch.swift:29:5:29:5 | { ... } |
| switch.swift:33:3:39:5 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 1 | getBody: | switch.swift:34:5:39:5 | { ... } |
| switch.swift:35:8:36:16 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 0 | getBody: | switch.swift:36:10:36:16 | { ... } |
| switch.swift:37:8:38:16 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 0 | getBody: | switch.swift:38:10:38:16 | { ... } |
| switch.swift:40:3:41:5 | case ... | getNumberOfLabels: | 1 | getNumberOfVariables: | 0 | getBody: | switch.swift:41:5:41:5 | { ... } |

View File

@@ -0,0 +1,13 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from CaseStmt x, int getNumberOfLabels, int getNumberOfVariables, Stmt getBody
where
toBeTested(x) and
not x.isUnknown() and
getNumberOfLabels = x.getNumberOfLabels() and
getNumberOfVariables = x.getNumberOfVariables() and
getBody = x.getBody()
select x, "getNumberOfLabels:", getNumberOfLabels, "getNumberOfVariables:", getNumberOfVariables,
"getBody:", getBody

View File

@@ -0,0 +1,13 @@
| switch.swift:3:4:5:7 | case ... | 0 | switch.swift:3:9:3:9 | =~ ... |
| switch.swift:6:4:7:20 | case ... | 0 | switch.swift:6:9:6:9 | =~ ... |
| switch.swift:6:4:7:20 | case ... | 1 | switch.swift:6:12:6:12 | =~ ... |
| switch.swift:8:4:9:18 | case ... | 0 | switch.swift:8:9:8:26 | x where ... |
| switch.swift:10:4:11:22 | case ... | 0 | switch.swift:10:4:10:4 | _ |
| switch.swift:22:3:23:5 | case ... | 0 | switch.swift:22:8:22:9 | .one |
| switch.swift:24:3:25:5 | case ... | 0 | switch.swift:24:8:24:40 | .two(...) where ... |
| switch.swift:26:3:27:5 | case ... | 0 | switch.swift:26:8:26:25 | .two(...) |
| switch.swift:28:3:29:5 | case ... | 0 | switch.swift:28:8:28:23 | .three(...) |
| switch.swift:33:3:39:5 | case ... | 0 | switch.swift:33:8:33:21 | .two(...) |
| switch.swift:35:8:36:16 | case ... | 0 | switch.swift:35:13:35:13 | =~ ... |
| switch.swift:37:8:38:16 | case ... | 0 | switch.swift:37:8:37:8 | _ |
| switch.swift:40:3:41:5 | case ... | 0 | switch.swift:40:3:40:3 | _ |

View File

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

View File

@@ -0,0 +1,7 @@
| switch.swift:8:4:9:18 | case ... | 0 | switch.swift:8:13:8:13 | x |
| switch.swift:24:3:25:5 | case ... | 0 | switch.swift:24:17:24:17 | a |
| switch.swift:24:3:25:5 | case ... | 1 | switch.swift:24:24:24:24 | b |
| switch.swift:26:3:27:5 | case ... | 0 | switch.swift:26:17:26:17 | c |
| switch.swift:26:3:27:5 | case ... | 1 | switch.swift:26:24:26:24 | d |
| switch.swift:28:3:29:5 | case ... | 0 | switch.swift:28:22:28:22 | e |
| switch.swift:33:3:39:5 | case ... | 0 | switch.swift:33:17:33:17 | a |

View File

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

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
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,4 @@
| switch.swift:2:1:12:1 | switch index { ... } | hasLabel: | no | getExpr: | switch.swift:2:8:2:8 | index | getNumberOfCases: | 4 |
| switch.swift:21:1:30:1 | switch x { ... } | hasLabel: | no | getExpr: | switch.swift:21:8:21:8 | x | getNumberOfCases: | 4 |
| switch.swift:32:1:42:1 | switch x { ... } | hasLabel: | yes | getExpr: | switch.swift:32:15:32:15 | x | getNumberOfCases: | 2 |
| switch.swift:34:5:39:5 | switch a { ... } | hasLabel: | yes | getExpr: | switch.swift:34:19:34:19 | a | getNumberOfCases: | 2 |

View File

@@ -0,0 +1,12 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from SwitchStmt x, string hasLabel, Expr getExpr, int getNumberOfCases
where
toBeTested(x) and
not x.isUnknown() and
(if x.hasLabel() then hasLabel = "yes" else hasLabel = "no") and
getExpr = x.getExpr() and
getNumberOfCases = x.getNumberOfCases()
select x, "hasLabel:", hasLabel, "getExpr:", getExpr, "getNumberOfCases:", getNumberOfCases

View File

@@ -0,0 +1,12 @@
| switch.swift:2:1:12:1 | switch index { ... } | 0 | switch.swift:3:4:5:7 | case ... |
| switch.swift:2:1:12:1 | switch index { ... } | 1 | switch.swift:6:4:7:20 | case ... |
| switch.swift:2:1:12:1 | switch index { ... } | 2 | switch.swift:8:4:9:18 | case ... |
| switch.swift:2:1:12:1 | switch index { ... } | 3 | switch.swift:10:4:11:22 | case ... |
| switch.swift:21:1:30:1 | switch x { ... } | 0 | switch.swift:22:3:23:5 | case ... |
| switch.swift:21:1:30:1 | switch x { ... } | 1 | switch.swift:24:3:25:5 | case ... |
| switch.swift:21:1:30:1 | switch x { ... } | 2 | switch.swift:26:3:27:5 | case ... |
| switch.swift:21:1:30:1 | switch x { ... } | 3 | switch.swift:28:3:29:5 | case ... |
| switch.swift:32:1:42:1 | switch x { ... } | 0 | switch.swift:33:3:39:5 | case ... |
| switch.swift:32:1:42:1 | switch x { ... } | 1 | switch.swift:40:3:41:5 | case ... |
| switch.swift:34:5:39:5 | switch a { ... } | 0 | switch.swift:35:8:36:16 | case ... |
| switch.swift:34:5:39:5 | switch a { ... } | 1 | switch.swift:37:8:38:16 | case ... |

View File

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

View File

@@ -0,0 +1,2 @@
| switch.swift:32:1:42:1 | switch x { ... } | outer |
| switch.swift:34:5:39:5 | switch a { ... } | inner |

View File

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

View File

@@ -0,0 +1,42 @@
let index = 42
switch index {
case 1:
print("1")
fallthrough
case 5, 10:
print("5, 10")
case let x where x >= 42:
print("big")
default:
print("default")
}
enum X {
case one
case two(_: Int, _: String)
case three(s: String)
}
let x = X.two(42, "foo")
switch x {
case .one:
break
case .two(let a, let b) where a == b.count:
break
case .two(let c, let d):
break
case .three(s: let e):
break
}
outer: switch x {
case .two(let a, _):
inner: switch a {
case 0:
break outer
default:
break inner
}
default:
break
}

View File

@@ -92,26 +92,26 @@ v5.8.swift:
# 19| getElement(0): [SwitchStmt] switch arr { ... }
# 19| getExpr(): [DeclRefExpr] arr
# 20| getCase(0): [CaseStmt] case ...
# 21| getBody(): [BraceStmt] { ... }
# 21| getElement(0): [IntegerLiteralExpr] 0
# 20| getLabel(0): [CaseLabelItem] ... is ...
# 20| getPattern(): [IsPattern] ... is ...
# 20| getCastTypeRepr(): [TypeRepr] [Int]
# 20| getSubPattern(): [NamedPattern] ints
# 20| getPattern().getFullyUnresolved(): [BindingPattern] let ...
# 20| getVariable(0): [ConcreteVarDecl] ints
# 20| Type = [Int]
# 21| getBody(): [BraceStmt] { ... }
# 21| getElement(0): [IntegerLiteralExpr] 0
# 22| getCase(1): [CaseStmt] case ...
# 23| getBody(): [BraceStmt] { ... }
# 23| getElement(0): [IntegerLiteralExpr] 1
# 22| getLabel(0): [CaseLabelItem] ... is ...
# 22| getPattern(): [IsPattern] ... is ...
# 22| getCastTypeRepr(): [TypeRepr] [Bool]
# 23| getBody(): [BraceStmt] { ... }
# 23| getElement(0): [IntegerLiteralExpr] 1
# 24| getCase(2): [CaseStmt] case ...
# 25| getBody(): [BraceStmt] { ... }
# 25| getElement(0): [IntegerLiteralExpr] 2
# 24| getLabel(0): [CaseLabelItem] _
# 24| getPattern(): [AnyPattern] _
# 20| [ConcreteVarDecl] ints
# 20| Type = [Int]
# 25| getBody(): [BraceStmt] { ... }
# 25| getElement(0): [IntegerLiteralExpr] 2
# 29| [StructDecl] Button
# 30| getMember(0): [PatternBindingDecl] var ... = ...
#-----| getInit(0): [NilLiteralExpr] nil

File diff suppressed because it is too large Load Diff

View File

@@ -868,7 +868,7 @@ class IsPattern(Pattern):
sub_pattern: optional[Pattern] | child
class NamedPattern(Pattern):
name: string
var_decl: VarDecl
class OptionalSomePattern(Pattern):
sub_pattern: Pattern | child
@@ -884,6 +884,7 @@ class TypedPattern(Pattern):
type_repr: optional["TypeRepr"] | child
@group("stmt")
@qltest.test_with("SwitchStmt")
class CaseLabelItem(AstNode):
pattern: Pattern | child
guard: optional[Expr] | child
@@ -948,10 +949,11 @@ class BreakStmt(Stmt):
target_name: optional[string]
target: optional[Stmt]
@qltest.test_with("SwitchStmt")
class CaseStmt(Stmt):
body: Stmt | child
labels: list[CaseLabelItem] | child
variables: list[VarDecl]
variables: list[VarDecl] | child
body: Stmt | child
class ContinueStmt(Stmt):
target_name: optional[string]